LeetCode刷题记录——15三数之和
一 题目记录:
给你一个包含n个整数的数组 nums,判断nums中是否存在三个元素a、b、c,使得 a + b + c = 0 ?,请你找出所有的满足条件不重复的三元组
【注】答案中不可以包含重复的三元组
示例:
-
给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
二 思路:
-
关键点在于去重,去除重复的计算。先讲数组排序,然后在按顺序遍历数组,设置两个指针,对数组的两端同时进行搜索,只有达到目标才进行下一次的循环
-
使用左右指针指向nums[i]后面的两端,判断nums[L]+nums[R]+nums[i]是否等于0,
- 如果 nums[i]大于 0,则三数之和必然无法等于 00,结束循环
- 如果 nums[i] == nums[i-1],则说明该数字重复,会导致结果重复,所以应该跳过
- 当 sum == 0 时,nums[L]== nums[L+1] 则会导致结果重复,应该跳过,L++
当 sum == 0 时,nums[R]== nums[R-1] 则会导致结果重复,应该跳过,R–
-
以下代码第一种会出现超时的情况,第二种不会
-
代码:
-
//出现超时情况 class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { int len = nums.size(); vector<vector<int>> ret; if(len < 3) return ret; sort(nums.begin(),nums.end()); int sum = 0; int p1=0,p2=0;//分别对应L和R for(int i = 0;i<len;i++){ if(nums[i]>0) break; if( i>0 && nums[i] == nums[i-1]) //去重 continue; p1 = i+1;//设置双指针 p2 = len-1; while(p1 <p2){ sum = nums[i] + nums[p1] + nums[p2]; if(sum == 0){ vector<int> vtemp{nums[i],nums[p1],nums[p2]}; ret.push_back(vtemp); vtemp.clear(); //去重 while(p1 < p2 &&nums[p1] == nums[p1+1]) p1++; while(p1<p2 && nums[p2] == nums[p2 - 1]) p2++; } else if(sum<0) p1++; else if(sum>0) p2--; } } return ret; } };
-
class Solution { public: vector<vector<int> > threeSum(vector<int>& nums) { vector<vector<int> > ret; int len = nums.size(); sort(nums.begin(),nums.end());//sort the input for(int i=0;i<len-2;i++){ //find the tripe for each nums[i] // j1 and j2 log the index of the other two numbers if(i ==0 ||(i>0 && nums[i] != nums[i-1])){ int p1 = i+1, p2 = len-1; // set two pointers while(p1 < p2){ if(nums[p1] + nums[p2] < -nums[i]){ p1++; }else if(nums[p1] + nums[p2] == -nums[i]){ if(p1 == i+1){ vector<int > vtemp{nums[i], nums[p1], nums[p2]}; ret.push_back(vtemp); vtemp.clear(); }else if(nums[p1] != nums[p1-1]){ vector<int > vtemp{nums[i], nums[p1], nums[p2]}; ret.push_back(vtemp); vtemp.clear(); } p1++,p2--; }else{ p2--; } } } } return ret; } };
-