15. 三数之和

发布时间 2023-07-25 18:19:56作者: tros

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

 

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 10

 

题解1:

时间
5804ms
击败 7.56%使用 Python3 的用户
内存
19.36mb
击败 7.31%使用 Python3 的用户
class Solution:
    # 二分查找
    def find(self, num: int, nums: list[int]) -> int:
        start = 0
        end = len(nums) - 1
        while start <= end:
            mid = (end + start) // 2
            item = nums[mid]
            if num == item:
                return mid
            elif num < item:
                end = mid - 1
            else:
                start = mid + 1

        return -1

    def threeSumSub(self, nums: list[int], arr: list[int], has_zero: bool) -> list[[int]]:
        res = []
        nums_len = len(nums)
        tempi = None
        for i in range(0, nums_len):
            vi = nums[i]
            if vi == tempi:
                continue
            tempi = vi
            if has_zero and vi < 0:
                index = self.find(-vi, arr)
                if index > -1:
                    res.append([vi, 0, -vi])

            tempj = None
            if i + 1 == nums_len:
                break
            for j in range(i + 1, nums_len):
                vj = nums[j]
                if vj == tempj:
                    continue
                tempj = vj

                vs = -(vi + vj)
                index = self.find(vs, arr)
                if index > -1:
                    res.append([vi, vj, vs])

        return res

    # 15. 三数之和
    def threeSum(self, nums: list[int]) -> list[list[int]]:
        res = []
        small = []
        zero = []
        big = []
        nums.sort()
        for item in nums:
            if item < 0:
                small.append(item)
            elif item == 0:
                zero.append(item)
            else:
                big.append(item)

        has_zero = len(zero) > 0
        res_small = self.threeSumSub(small, big, has_zero)
        res_big = self.threeSumSub(big, small, has_zero)
        res = res_small + res_big
        if len(zero) > 2:
            res.append([0, 0, 0])

        return res