LeetCode 15.三数之和
Posted 阿乐246
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 15.三数之和相关的知识,希望对你有一定的参考价值。
一、题目详情
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意: 答案中不可以包含重复的三元组。
示例:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
二、思路
首先能想到的就是嵌套三层循环,找到所有满足条件的组合,然后再进行复杂繁琐的去重操作,太过麻烦,时间复杂度O(N³)。
而先进行去重操作,然后使用普通的三层循环,这样比较简单。为了保证答案不重复,直接将数组中的元素进行从小到大的排序。
同时,对于每一重循环,相邻两次枚举的元素不能相同,否则也会造成重复。
三、算法
伪代码实现:
nums.sort()
for first = 0 .. n-1
// 只有和上一次枚举的元素不相同,我们才会进行枚举
if first == 0 or nums[first] != nums[first-1] then
for second = first+1 .. n-1
if second == first+1 or nums[second] != nums[second-1] then
for third = second+1 .. n-1
if third == second+1 or nums[third] != nums[third-1] then
// 判断是否有 a+b+c==0
check(first, second, third)
优化:
如果有三元组(a,b,c),满足a+b+c=0,当第二重循环向右枚举下一个元素b’时,因为b’>b,那么满足a+b’+c’=0的c’一定有c’<c。
所以可以使用双指针的方法,第二重循环不变继续从左向右,第三重循环从右向左。
总的时间复杂度,也变成了O(N²)。
nums.sort()
for first = 0 .. n-1
if first == 0 or nums[first] != nums[first-1] then
// 第三重循环对应的指针
third = n-1
for second = first+1 .. n-1
if second == first+1 or nums[second] != nums[second-1] then
// 向左移动指针,直到 a+b+c 不大于 0
while nums[first]+nums[second]+nums[third] > 0
third = third-1
// 判断是否有 a+b+c==0
check(first, second, third)
四、代码
class Solution
public List<List<Integer>> threeSum(int[] nums)
int length=nums.length;
Arrays.sort(nums);
List<List<Integer>> ans=new ArrayList<List<Integer>>();
for(int i=0;i<length;i++)
if(i!=0 && nums[i]==nums[i-1])
continue;
int k=length-1; //在第二重循环外初始化k
for(int j=i+1;j<length;j++)
if(j!=i+1 && nums[j]==nums[j-1])
continue;
while(nums[i]+nums[j]+nums[k]>0 && j<k)
k--;
//指针重合之后,b继续增加,不可能再有满足条件的c了
if(j==k)
break;
if(nums[i]+nums[j]+nums[k]==0)
List<Integer> temp=new ArrayList<Integer>();
temp.add(nums[i]);
temp.add(nums[j]);
temp.add(nums[k]);
ans.add(temp);
return ans;
以上是关于LeetCode 15.三数之和的主要内容,如果未能解决你的问题,请参考以下文章