• 题目要求:

image.png

  • 思路

    • 定义一个res[]用来保存结果集
    • 先把数组排个序,这样遇到重复的数字可以直接到下一个
    • 遍历数组,只遍历数组下标位置从0到数组长度-2的位置即可
    • 如果nums[i] + nums[i+1] + nums[i+2]之和大于0,说明当前遍历到的位置之后的所有元素的三个元素之和一定大于0,因为数组是排好序的,此时break出循环
    • 如果当前的元素与数组最后两个元素之和小于零,说明当前元素太小了,和最大的两个数之和都小于零,此时直接遍历下一个数组元素(continue)
    • 如果数组下标大于0,而且,如果当前元素与前一个元素相等,此时直接遍历下一个数组元素(continue)
    • 在循环中定义一个l(left),l的值为当前数组元素下标i的下一个,定义一个r(right),为数组元素的最后一位,也就是nums[i]为当前的数值,剩余的两个值要从左向右,从右向左往中间找,直至l与r重合
    • 用l和r遍历i右侧的数组元素时,定义一个tmp来保存当前nums[i]、nums[l]、nums[r]的和

      • 如果当前的tmp等于0,说明三个数字找到了,把[nums[i],nums[l],nums[r]]这三个数组成的数组append到res结果集中,然后用while循环找到下一个数组元素不等于当前nums[l]的元素的下标,判断条件为l小于l,当前的l和下一个l+1的数组元素值是否相等,如果相等,直接把l加一,r也是一样
      • 寻找不重复元素的while循环结束之后,当前的l是最后一位等于当前的nums[l]的值,所以把l加一,r也是同理
      • 如果当前的tmp值小于0,说明当前的r和l的和偏小,l加一
      • 如果当前的tmp值大于0,说明当前的r和l的和偏大,r减一
    • 最后返回结果集res
  • 核心代码:
#n为数组长度
n = len(nums)
#用来保存结果集
res = []
#把数组排序
nums.sort()

#遍历排序的数组
for i in range(n-2):
    #如果当前的值与下一个值还有下下个值得和大于0,后面就都没有和等于0的值了,因为数组是排好序的,此时跳出循环
    if nums[i] + nums[i+1] + nums[i+2] > 0:
        break
    #如果当前的值与数组的最后两个值之和都小于0,说明当前的值太小了,继续遍历下一位元素
    if nums[i] + nums[n-2] + nums[n-1] < 0:
        continue
    #如果当前的元素下标不为0,而且当前的元素与前一个元素的值相等,说明元素重复了,直接遍历下一个
    if i > 0 and nums[i] == nums[i-1]:
        continue
    #l用来表示i的下一个,r用来表示数组的最后一位元素,r和l向中心靠拢,寻找下标为i,r,l和为0的元素
    l = i + 1
    r = n - 1
    #当l小于r时,循环
    while l < r:
        #定义一个tmp来保存当前的三个数的和
        tmp = nums[i] + nums[l] + nums[r]
        #如果和为0
        if tmp == 0:
            #和为0说明找到了三个数,把这三个数作为一整个数组,加到结果集中
            res.append([nums[i],nums[l],nums[r]])
            #然后判断l的下一位是否是重复的,如果重复l加一
            while l < r and nums[l] == nums[l+1]:
                l += 1
            #当前的nums[l]为最后一位与之前的nums[l]相等的值,所以l还要加一
            l += 1
            #r也是同理
            while l < r and nums[r] == nums[r-1]:
                r -= 1
            r -= 1
        #如果三个数的和小于0,说明三个数的和偏小,l要向右移
        elif tmp < 0:
            l += 1
        #如果三个数的和大于0,说明三个数的和偏大,r向左移
        else:
            r -= 1
#返回结果集
return res
  • 完整代码:
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """  
        n = len(nums)
        res = []
        nums.sort()

        for i in range(n-2):
            if nums[i] + nums[i+1] + nums[i+2] > 0:
                break
            if nums[i] + nums[n-2] + nums[n-1] < 0:
                continue
            if i > 0 and nums[i] == nums[i-1]:
                continue
            l = i + 1
            r = n - 1
            while l < r:
                tmp = nums[i] + nums[l] + nums[r]
                if tmp == 0:
                    res.append([nums[i],nums[l],nums[r]])
                    while l < r and nums[l] == nums[l+1]:
                        l += 1
                    l += 1
                    while l < r and nums[r] == nums[r-1]:
                        r -= 1
                    r -= 1
                elif tmp < 0:
                    l += 1
                else:
                    r -= 1
            
        return res

Adrianna
1 声望2 粉丝