【LeetCode】15. 三数之和

105 阅读1分钟

Description

Array Two Pointers Hash

URL: leetcode-cn.com/problems/3s…

思路

  • 暴力求解三重循环[X]
  • 哈希表存储
  • 双指针向中间推进

Python

哈希表

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 制作字典和零值个数
        p, n, zero, res = {}, {}, 0, []
        for num in nums:
            if num == 0: zero += 1
            elif num > 0:
                if p.get(num): p[num] += 1
                else: p[num] = 1
            else:
                if n.get(num): n[num] += 1
                else: n[num] = 1
        # 分析边界情况
        if zero >= 3:
            res.append([0, 0, 0])
        if zero > 0:
            for num in p.keys():
                if n.get(-num): res.append([num, -num, 0])
        # 分析两个相同的正数+一个负数 or 两个相同的负数+一个正数
        for num in p.keys():
            if p[num] >= 2:
                if n.get(-2 * num): res.append([num, num, -2 * num])
        for num in n.keys():
            if n[num] >= 2:
                if p.get(-2 * num): res.append([num, num, -2 * num])
        # 分析两个不同的正数+一个负数 or 两个不同的负数+一个正数
        p_keys = list(p.keys())
        for i in range(len(p_keys) - 1):
            num1 = p_keys[i]
            for num2 in p_keys[i + 1:]:
                if n.get(- num1 - num2): res.append([num1, num2, -(num1 + num2)])
        n_keys = list(n.keys())
        for i in range(len(n_keys) - 1):
            num1 = n_keys[i]
            for num2 in n_keys[i + 1:]:
                if p.get(- num1 - num2): res.append([num1, num2, -(num1 + num2)])
        return res

双指针

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res = []
        for i in range(len(nums) - 2):
            if nums[i] > 0: break
            if i > 0 and nums[i] == nums[i - 1]: continue
            left, right = i + 1, len(nums) - 1
            while left < right:
                s = nums[i] + nums[left] + nums[right]
                if s == 0:
                    res.append([nums[i], nums[left], nums[right]])
                    left += 1
                    right -= 1
                    while left < right and nums[left] == nums[left - 1]: left += 1
                    while left < right and nums[right] == nums[right + 1]: right -= 1
                elif s > 0:
                    right -= 1
                    while left < right and nums[right] == nums[right + 1]: right -= 1
                else:
                    left += 1
                    while left < right and nums[left] == nums[left - 1]: left += 1
        return res

第一行是双指针法;第二行是哈希表法

(哈希表永远滴神)


END |ू・ω・` )