三数之和的问题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
这样的代码就不会出现超时的情况了。
以上就是本期的全部内容!!!