LeetCode 18. 4Sum
阿新 • • 發佈:2018-03-21
文章 相等 return 代碼 復雜 避免 ont 易懂 博客園
問題鏈接
LeetCode 18. 4Sum
題目解析
給定n元素的數組,求出滿足 \(a+b+c+d = target\) 的所有元組。
解題思路
已經成為一個系列了,這道題是 LeetCode 15. 3Sum 的升級版,思路與其也是一模一樣,外層再加一層循環。
先將數組排好序,便於檢測重復。最外層循環固定最小數字 \(a\),第二層循環固定第二小數字 \(b\),左右指針分別代表 \(c\) 和 \(d\) ,從兩邊向中間移動。
註意避免重復,本題中通過判斷相鄰數字相等直接跳過的方法去重,米面了使用 set容器,簡單易懂。
時間復雜度:\(O(n^3)\)。
參考代碼
class Solution {
public :
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector< vector<int> > res;
if(nums.size() < 4) return res;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size()-3; i++) {
if(i > 0 && nums[i] == nums[i-1])//避免重復
continue;
for(int j = i+1; j < nums.size()-2; j++) {
if(j > i + 1 && nums[j] == nums[j - 1])//再次避免重復
continue;
int left = j + 1, right = nums.size() - 1;
while (left < right ) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if(sum < target) left++;
else if(sum > target) right--;
else {
res.push_back({nums[i], nums[j], nums[left], nums[right]});
while(left + 1 < right && nums[left+1] == nums[left])//避免重復
left++;
while(right -1 > left && nums[right-1] == nums[right])//避免重復
right--;
left++; right--;
}
}
}
}
return res;
}
};
擴展
在問題討論中看到一種效率超群的做法:7ms java code win over 100%。時間復雜度雖然也是 \(O(n^3)\),實際確實快了不少。通過將4Sum問題分解成3Sum和2Sum問題,其實就是將上述的最外兩層循環分別拆成函數,添加更多的條件,可以及時判斷不合理情況,從而使效率提高不少。
再深入想一想,我們見過了2Sum、3Sum和4Sum,其實可以泛化成 K-Sum 問題,找到了一篇講的還不錯的文章:k sum problem。
相似題目
LeetCode 1. Two Sum
LeetCode 15. 3Sum
LeetCode 16. 3Sum Closest
LeetCode All in One題解匯總(持續更新中...)
本文版權歸作者AlvinZH和博客園所有,歡迎轉載和商用,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利.
LeetCode 18. 4Sum