題目地址
https://leetcode-cn.com/problems/3sum/
思路
哈希解法
去重的過程不好處理,有很多小細節,如果在面試中很難想到位
時間複雜度:O(n^2),但是運行時間很長,不好做剪枝操作
雙指針
推薦使用這個方法,排序後用雙指針前後操作,比較容易達到去重的目的,但也有一些細節需要注意,我在如下代碼詳細註釋了需要注意的點
時間複雜度:O(n^2)
哈希法代碼
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
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) {
continue;
}
if (i > 0 && nums[i] == nums[i - 1]) { //三元組元素a去重
continue;
}
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去重
continue;
}
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]);
}
}
}
return result;
}
};
雙指針法代碼
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
// 排序之後如果第一個元素已經大於零,那麼無論如何組合都不可能湊成三元組,直接返回結果就可以了
if (nums[i] > 0) {
return result;
}
// 錯誤去重方法,將會漏掉-1,-1,2 這種情況
/*
if (nums[i] == nums[i + 1]) {
continue;
}
*/
// 正確去重方法
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;
int right = nums.size() - 1;
while (right > left) {
// 去重複邏輯如果放在這裏,0,0,0 的情況,可能直接導致 right<=left 了,從而漏掉了 0,0,0 這種三元組
/*
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
*/
if (nums[i] + nums[left] + nums[right] > 0) {
right--;
} else if (nums[i] + nums[left] + nums[right] < 0) {
left++;
} else {
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
// 去重邏輯應該放在找到一個三元組之後
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
// 找到答案時,雙指針同時收縮
right--;
left++;
}
}
}
return result;
}
};
更多精彩文章持續更新,可以微信搜索「 代碼隨想錄」第一時間閱讀,關注後有大量的學習資料和簡歷模板可以免費領取,本文 GitHub:https://github.com/youngyangyang04/leetcode-master 已經收錄,歡迎star,fork,共同學習,一起進步。