三数之和的问题python代码描述

三数之和的问题python代码描述

题目描述:

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

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

这道题目想要完成不难,先来看一下我原来的代码

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        d=[]
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                for m in range(j+1,len(nums)):
                    if nums[i]+nums[j]+nums[m]==0 and i!=j and j!=m and i!=m:
                        dd=[nums[i],nums[j],nums[m]]
                        dd.sort()
                        if dd not in d:
                            d.append(dd)
        d.sort()
        return d

很显然上面的代码用了三次循环和许多语句,运行时间不容乐观,然后我对以上代码进行了简写

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        d=[]
        nums.sort()
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                for m in range(j+1,len(nums)):
                    if nums[i]+nums[j]+nums[m]==0 and i!=j and j!=m and i!=m:
                        dd=[nums[i],nums[j],nums[m]]
                        if dd not in d:
                            d.append(dd)
        d.sort()
        return d

然而运行时间还是超时,所以我开始探询新的方法去完成这个程序,所以我用了C++去做,运行时间(88 ms)

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> >n;
        sort(nums.begin(),nums.end());
        int h1;
        h1=nums.size();
        if(nums.empty() || nums.front()>0 || nums.back()<0)
            return {};
        
        for(int i=0;i<h1;i++)
        {
            int fix=nums[i];
            if(fix>0)    break;
            if(i>0 && fix==nums[i-1])    continue;
            //对撞指针
            int l=i+1,r=h1-1;
            while(l<r)
            {
                if(nums[l]+nums[r]==-fix  )
                {
                    if(l==i+1 || r==h1-1)
                    {
                        n.push_back(vector<int>{nums[i],nums[l],nums[r]});
                        l++;r--;
                    }
                    else if(nums[l]==nums[l-1])
                        l++;
                    else if(nums[r]==nums[r+1])
                        r--;
                    else{
                        n.push_back(vector<int>{nums[i],nums[l],nums[r]});
                        l++;r--;
                    }
                    
                }
                else if(nums[l]+nums[r]<-fix)
                    l++;
                else
                    r--;
            }
        }
        return n;
    }
};

用上面的C++程序没有超时的问题,但是Python作为解释性语言,运行时间本就比C++长,所以我又对用Python代码解决问题展开了思考,然后觉得可以通过双指针来试试,代码如下,运行时间(788 ms)

'''注意Python是没有指针的,只是用数组模拟指针的形式'''
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        d=[]
        #枚举h1
        for i in range(len(nums)):
            if i>0 and nums[i]==nums[i-1]:
                continue
            # h3对应的指针初始指向列表的最右端
            m=len(nums)-1    #注意列表的长度和标号是差一个数的
            t=-nums[i]
            #枚举h2
            for j in range(i+1,len(nums)):
                if j>i+1 and nums[j]==nums[j-1]:
                    continue
                # 必须保证 h2 的指针在 h3 的指针的左侧
                while j<m and nums[j]+nums[m]>t:
                    m-=1
                '''如果指针重合,随着 h2后续的增加就不会有满足 h1+h2+h3=0 
                并且 h2<h3 的 h3 了,可以退出循环'''
                if j==m:
                    break
                if nums[j]+nums[m]==t:
                    d.append([nums[i],nums[j],nums[m]])
        return d

这样的代码就不会出现超时的情况了。
以上就是本期的全部内容!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员阿诺斯

您的打赏是我创作路上最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值