#10_力扣打卡第十天(14)

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 请你找出所有和为 0 且不重复的三元组。

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

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:

输入:nums = []
输出:[]
示例 3:

输入:nums = [0]
输出:[]
 

提示:

0 <= nums.length <= 3000
-105 <= nums[i] <= 105

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
 

思路:

看到这道题,第一个想法就是暴力破解,用i,j,k三层循环,然后用if判断语句来解决。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        ans=[]
        l=len(nums)
        for i in range(l):
            for j in range(i+1,l):
                 for k in range(j+1,l):
                    if nums[i]+nums[j]+nums[k]==0:
                        s=sorted([nums[i], nums[j],nums[k]])
                        if s not in ans:
                            ans.append(s)
        return ans

毫无疑问,超时了!

 

思路:

然后,又想到一个法子,由于a+b+c=0,将c=-(a+b),通过空间换时间的思路,将所有的a+b的和建立成一个二维数组,再从原nums中寻找有无和-(a+b)相同的数,如果有就输出,可惜磨了一下午也搞不出来这个二维数组,以后有机会再搞(cy)。

然后看了答案的一部分思路,想通过双指针来搞,结果。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        ans=[]
        nums.sort()
        for i in range(len(nums)):
            if i==len(nums)-2:
                break
            else:
                for j in range(i+1,len(nums)):
                    if j == len(nums) - 1:
                        break
                    end=len(nums)-1
                    while end>j and nums[i]+nums[j]+nums[end]>0:
                         end-=1
                    if end==j:
                        break
                    if nums[i]+nums[j]+nums[end]==0 and [nums[i],nums[j],nums[end]] not in ans:
                        ans.append([nums[i],nums[j],nums[end]])
        return ans

咋还超时。

接着看看详细的思路。

nums= [-1,0,1,2,-1,-4]
n = len(nums)
nums.sort()
print(nums)
ans=[]
for first in range(n):
    # 需要和上一次枚举的数不相同
    if first > 0 and nums[first] == nums[first - 1]:
        continue
    # c 对应的指针初始指向数组的最右端
    third = n - 1
    target = -nums[first]
    # 枚举 b
    for second in range(first + 1, n):
        # 需要和上一次枚举的数不相同
        if second > first + 1 and nums[second] == nums[second - 1]:
            continue
        # 需要保证 b 的指针在 c 的指针的左侧
        while second < third and nums[second] + nums[third] > target:
            third -= 1
        # 如果指针重合,随着 b 后续的增加
        # 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
        if second == third:
            break
        if nums[second] + nums[third] == target:
            ans.append([nums[first], nums[second], nums[third]])


print(ans)


 看了答案后,我悟了,之前我通过判断是否与后一个数字不同,来遍历寻找答案,结果总是少一个答案。

如图。

nums= [-1,0,1,2,-1,-4]
ans=[]
nums.sort()
print(nums)
for i in range(len(nums)):
    if i==len(nums)-2:
        break
    else:
        for j in range(i+1,len(nums)):
            if j == len(nums) - 1:
                break
            if nums[j] == nums[j + 1] :
                continue
            end=len(nums)-1
            while end>j and nums[i]+nums[j]+nums[end]>0:
                end-=1
            if end==j:
                break
            if nums[i]+nums[j]+nums[end]==0 and [nums[i],nums[j],nums[end]] not in ans:
                ans.append([nums[i],nums[j],nums[end]])

print(ans)

后来发现了错误,真是细节。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值