1:两数之和
这道题三种做法:
暴力法;
两次哈希法。map<int,int>。key为值,value为id。 全部放入后。从0开始遍历,如果存在sum-num【i】,并且value的i不是用一个,则可以
一次哈希法。每次放入值前,检测一下之前的是否有满足条件的
15. 三数之和
for第一个数字,如果第一个数字重复,则跳过。
之后我们确定好target=-nums[第一个数字]。
第三个数字从n找
for第二个数字,如果重复则跳过。如果第二个+第三个大于target了,说明第三个大了。第三个数字往左移动。一直着用走,直到小于等于。如果等于则更新。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
// 枚举 a
for (int first = 0; first < n; ++first) {
// 需要和上一次枚举的数不相同
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
// c 对应的指针初始指向数组的最右端
int third = n - 1;
int target = -nums[first];
// 枚举 b
for (int second = first + 1; second < n; ++second) {
// 需要和上一次枚举的数不相同
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while (second < third && nums[second] + nums[third] > target) {
--third;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if (second == third) {
break;
}
if (nums[second] + nums[third] == target) {
ans.push_back({nums[first], nums[second], nums[third]});
}
}
}
return ans;
}
};
16. 最接近的三数之和
for遍历第一个值,如果重复则跳过。
内部l=i+1,r=n-1.
while(l<r)
{
如果三者相加等于sum,直接returm
计算差值。
大了r左移,小了l右移。注意去重
}
