Leetcode15. 三数之和

一、题目描述:

给你一个整数数组 n u m s nums nums ,判断是否存在三元组 [ n u m s [ i ] , n u m s [ j ] , n u m s [ k ] ] [nums[i], nums[j], nums[k]] [nums[i],nums[j],nums[k]] 满足 i ≠ j i \neq j i=j i ≠ k i \neq k i=k j ≠ k j \neq k j=k ,同时还满足 n u m s [ i ] + n u m s [ j ] + n u m s [ k ] = 0 nums[i] + nums[j] + nums[k] = 0 nums[i]+nums[j]+nums[k]=0 。请你返回所有和为 0 且不重复的三元组。

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

  1. 示例 1:
    • 输入: n u m s = [ − 1 , 0 , 1 , 2 , − 1 , − 4 ] nums = [-1,0,1,2,-1,-4] nums=[1,0,1,2,1,4]
    • 输出: [ [ − 1 , − 1 , 2 ] , [ − 1 , 0 , 1 ] ] [[-1,-1,2],[-1,0,1]] [[1,1,2],[1,0,1]]
    • 解释:
      • n u m s [ 0 ] + n u m s [ 1 ] + n u m s [ 2 ] = ( − 1 ) + 0 + 1 = 0 nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 nums[0]+nums[1]+nums[2]=(1)+0+1=0
      • n u m s [ 1 ] + n u m s [ 2 ] + n u m s [ 4 ] = 0 + 1 + ( − 1 ) = 0 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 nums[1]+nums[2]+nums[4]=0+1+(1)=0
      • n u m s [ 0 ] + n u m s [ 3 ] + n u m s [ 4 ] = ( − 1 ) + 2 + ( − 1 ) = 0 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 nums[0]+nums[3]+nums[4]=(1)+2+(1)=0
      • 不同的三元组是 [ − 1 , 0 , 1 ] [-1,0,1] [1,0,1] [ − 1 , − 1 , 2 ] [-1,-1,2] [1,1,2]
      • 注意,输出的顺序和三元组的顺序并不重要。
  2. 示例 2:
    • 输入: n u m s = [ 0 , 1 , 1 ] nums = [0,1,1] nums=[0,1,1]
    • 输出: [ ] [] []
    • 解释:唯一可能的三元组和不为 0 。
  3. 示例 3:
    • 输入: n u m s = [ 0 , 0 , 0 ] nums = [0,0,0] nums=[0,0,0]
    • 输出: [ [ 0 , 0 , 0 ] ] [[0,0,0]] [[0,0,0]]
    • 解释:唯一可能的三元组和为 0 。
  • 提示:
    • 3 ≤ n u m s . l e n g t h ≤ 3000 3 \leq nums.length \leq 3000 3nums.length3000
    • − 1 0 5 ≤ n u m s [ i ] ≤ 1 0 5 -10^5 \leq nums[i] \leq 10^5 105nums[i]105

二、解决思路和代码

1. 解决思路
  • 分析:题目中指定三数之和是0,那么这三个数字有大有小,我们可以先对数组中的数字进行排序,然后使用三个指针遍历
    • step1: 对数组中的数值排序。(python中可以使用 nums.sort())

    • step2: 三指针查找和为 0 的三个数

2. 代码
 from typing import *
 class Solution:
     ## 快速排序算法
     def quickSort(self, nums: List[int], start: int, end: int):   
         if start>end: return
         left, right = start, end
         temp = nums[left]
         while left < right:
             while left<right and nums[right]>=temp: right-=1
             if left < right:
                 nums[left] = nums[right]
                 left += 1
                 
             while left<right and nums[left]<=temp: left += 1
             if left<right:
                 nums[right] = nums[left]
                 right -= 1
         nums[left] = temp
         self.quickSort(nums, start, left-1)
         self.quickSort(nums, left+1, end)
         return
           
     def threeSum(self, nums: List[int]) -> List[List[int]]:
         nums2 = nums.copy()
         res = []
         ## step1: 对数组进行排序
         self.quickSort(nums2, 0, len(nums2)-1)

         ## step2: 三指针遍历
         for i in range(len(nums2)):
             left, right = i+1, len(nums2)-1
             while left<right:
                 if nums2[i]+nums2[left]+nums2[right]==0:
                     if [nums2[i],nums2[left],nums2[right]] not in res:
                         res.append([nums2[i],nums2[left],nums2[right]])
                     left += 1
                     right -= 1     
                 while left<right and nums2[i]+nums2[left]+nums2[right]>0: right-=1
                 while left<right and nums2[i]+nums2[left]+nums2[right]<0: left+=1
         return res
 ```

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值