Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修正 0015.三数之和.md 中的严重表述错误 #2526

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 30 additions & 17 deletions problems/0015.三数之和.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,35 +50,48 @@
```CPP
class Solution {
public:
// 在一个数组中找到3个数形成的三元组,它们的和为0,不能重复使用(三数下标互不相同),且三元组不能重复。
// 理论解法:a+b+c(存储)==0(检索) <=> c(存储)==0-(a+b)(检索)
// 实际解法:a+b+c(存储)==0(检索) <=> b(存储)==0-(a+c)(检索)
vector<vector<int>> threeSum(vector<int>& nums) {
// 本解法的内层循环一边存储一边检索,所以被存储的应该是b,而不是c
vector<vector<int>> result;
sort(nums.begin(), nums.end());
// 找出a + b + c = 0
// a = nums[i], b = nums[j], c = -(a + b)

for (int i = 0; i < nums.size(); i++) {
// 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
if (nums[i] > 0) {
// 如果a是正数,a<b<c,不可能形成和为0的三元组
if (nums[i] > 0)
break;
}
if (i > 0 && nums[i] == nums[i - 1]) { //三元组元素a去重

// [a, a, ...] 如果本轮a和上轮a相同,那么找到的b,c也是相同的,所以去重a
if (i > 0 && nums[i] == nums[i - 1])
continue;
}

// 这个set的作用是存储b
unordered_set<int> set;
for (int j = i + 1; j < nums.size(); j++) {
if (j > i + 2
&& nums[j] == nums[j-1]
&& nums[j-1] == nums[j-2]) { // 三元组元素b去重

for (int k = i + 1; k < nums.size(); k++) {
// [(-2x), ..., (x), (x), x, x, x, ...]
// eg. [0, 0, 0]
// eg. [-4, 2, 2]
// eg. [(-4), -1, 0, 0, 1, (2), (2), {2}, {2}, 3, 3]
// 去重b=c时的b和c,即第三个x到最后一个x需要被跳过
if (k > i + 2 && nums[k] == nums[k - 1] && nums[k - 1] == nums[k - 2])
continue;

// a+b+c=0 <=> b=0-(a+c)
int target = 0 - (nums[i] + nums[k]);
if (set.find(target) != set.end()) {
result.push_back({nums[i], target, nums[k]}); // nums[k]成为c
// 内层循环中,a固定,如果find到了和上轮一样的b,那么c也就和上轮一样,所以去重b
set.erase(target);
}
int c = 0 - (nums[i] + nums[j]);
if (set.find(c) != set.end()) {
result.push_back({nums[i], nums[j], c});
set.erase(c);// 三元组元素c去重
} else {
set.insert(nums[j]);
else {
set.insert(nums[k]); // nums[k]成为b
}
}
}

return result;
}
};
Expand Down