1. 程式人生 > >LeetCode 18. 4Sum

LeetCode 18. 4Sum

文章 相等 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