版权声明:欢迎指出错误,作者极懒,常常懒得修改 https://blog.csdn.net/KevinAshen/article/details/89417847
题目引入
题目: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;
sort(nums.begin(), nums.end());
if (nums.empty() || nums.front() > 0 || nums.back() < 0) {
return res;
}
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > 0) {
break;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int target = 0 - nums[i];
int k = i + 1, j = nums.size() - 1;
while (k < j) {
if (nums[k] + nums[j] == target) {
res.push_back({nums[i], nums[k], nums[j]});
while (k < j && nums[k] == nums[k + 1]) {
k++;
}
while (k < j && nums[j] == nums[j - 1]) {
j--;
}
k++;
j--;
} else if (nums[k] + nums[j] < target) {
k++;
} else {
j--;
}
}
}
return res;
}
};
简单分析
-
这道题上来肯定是要排序,在有序的基础上我们的左右指针才有了意义
-
我们先定义一个fix数,确定之后我们需要的就是寻找target - fix的两数之和,此时就可以使用左右指针
- 因为最开始的左数是最小数,右数是最大数,因此如果结果偏大只要右指针往左,右数变小(结果偏小同理)
- 此外要考虑重复数字的问题,对于重复的数字,我们需要跳过
- 但这不是说5, 5, 5这样就不对了,而是说对于fix,left,right都必须是特有数,而不能有两个一样的left
类似题目
后记
- 左右指针建立在排序的基础上,对于找两数之和等很有效