leetcode 15.三数之和
程序员文章站
2022-07-15 11:16:48
...
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]
]
解题思路
该题正确的解法是采用双指针的方法,也可以采用回溯法(时间复杂度太高,会超时)。在双指针的写法后面,再补上回溯法的解题方法,可以锻炼一下回溯法的解题思维。
对于该题,首先选择数组中的一个元素作为第一个数,然后其后面通过双指针去获得其他两个数,采用双层循环的方式。具体细节:给定的数组是无序的,并且里面包含重复的元素,要进行排序处理,为什么要进行排序呢?因为在双指针获取其他两个数的时候,只有数组是有序的,才可以知道两个指针是否移动(这里如果不理解看代码)。为了避免目标数组的重复,需要加一些边界条件的判断(具体看代码)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
// nums的个数小于3,表示没有符合的条件,直接返回
if(nums.size() < 3){
return res;
}
// nums数组排序
sort(nums.begin(), nums.end());
for(int i=0; i<nums.size(); i++){
int l = i+1;
int r = nums.size()-1;
// 当第一个数字大于零的时候,后面的数字也都大于零,表示后面的数都不符合条件,直接跳出循环
if(nums[i] > 0){
break;
}
// 避免重复; 这是第一个数字的选择,如果当期的数和前一个数相同,继续下一步操作,筛选出来的数就和前一个数的结果相同,就会产生重复的数组,所以这里就直接continue,进入下一次循环中。
if(i>0 && nums[i] == nums[i-1]){
continue;
}
while(l<r){
// 找到符合条件的三个数
if(nums[i]+nums[l]+nums[r] == 0){
vector<int> temp = {nums[i], nums[l], nums[r]};
l++; // 左指针加1
// 这里也是为了避免重复,给第二个数的筛选条件条件,原理和第一个数的筛选相似
if(nums[l] == nums[l-1]){
// 如果l和r两个指针相遇了,依然相等,表示后面没有数字了,就把当前结果添加进去
if(l == r){
res.push_back(temp);
}
continue;
}
res.push_back(temp);
}
// 大于零,右指针减1
else if(nums[i]+nums[l]+nums[r] > 0){
r--;
}
// 小于零,左指针加1
else{
l++;
}
}
}
return res;
}
};
回溯法
使用回溯法,就是让程序去尝试着遍历每一种可能的结果,这里时间复杂度太高,结果超时,可以锻炼一下回溯的思维
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
vector<int> track;
sort(nums.begin(), nums.end());
backTrack(res, nums, track, 0);
return res;
}
void backTrack(vector<vector<int>>& res, vector<int> nums, vector<int> track, int index){
if(track.size() == 3){
if(track[0] + track[1] + track[2] == 0){
if(find(res.begin(), res.end(), track) == res.end()){
res.push_back(track);
}
}
return;
}
for(int i=index; i<nums.size(); i++){
track.push_back(nums[i]);
backTrack(res, nums, track, i+1);
track.pop_back();
}
}
};
欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步
上一篇: LeetCode:15.三数之和
下一篇: 【LeetCode】15. 三数之和