leetcode 18 --- 4sum
生活随笔
收集整理的這篇文章主要介紹了
leetcode 18 --- 4sum
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1? 題目
給出一個有n個元素的數組S,S中是否有元素a,b,c和d滿足a+b+c+d=目標值?找出數組S中所有滿足條件的四元組。
注意:
2? 解法
2.1? 我的第一版解法
寫思路:
用循環的方法嘗試所有的四個數組合。
我的第一版代碼:
class Solution { public:vector<vector<int> > fourSum(vector<int> &num, int target) {vector<vector<int> > res;if (num.size() < 4) {return res;}sort(num.begin(), num.end());for (int i = 0; i < num.size() - 3; i++) {for (int j = i + 1; j < num.size() - 2; j ++) {for (int k = j + 1; k < num.size() - 1; k ++) {for (int n = k + 1; n < num.size(); n ++) {if (num[i] + num[j] + num[k] + num[n] == target) {vector<int> tmp_res = {num[i], num[j], num[k], num[n]};res.push_back(tmp_res);}}}}}return res;} };結果發現過不了:
因為結果中有相同的數組:[-3,0,1,2],[-3,0,1,2],原因是有多個0實例,第一個[-3,0,1,2]用的一號0,第二個[-3,0,1,2]用的二號0.
2.2? 我的第二版解法
思路:
因為先把數組從小到大排序完成了,所以相同的數只用第一個,用完之后執行檢查直到下一個不一樣的數。
代碼:
class Solution { public:vector<vector<int> > fourSum(vector<int> &num, int target) {vector<vector<int> > res;if (num.size() < 4) {return res;}sort(num.begin(), num.end());for (int i = 0; i < num.size() - 3;) {for (int j = i + 1; j < num.size() - 2;) {for (int k = j + 1; k < num.size() - 1;) {for (int n = k + 1; n < num.size();) {if (num[i] + num[j] + num[k] + num[n] == target) {vector<int> tmp_res = {num[i], num[j], num[k], num[n]};res.push_back(tmp_res);}while (++n < num.size() && num[n] == num[n - 1]){}}while (++k < num.size() - 1 && num[k] == num[k - 1]){}}while (++j < num.size() - 2 && num[j] == num[j - 1]){}}while (++i < num.size() - 3 && num[i] == num[i - 1]){}}return res;} };結果發現性能很差:
2.3? 我的第三版解法
思路:
后來想出來一個點,因為這個數列是遞增的,所以第一個數要不大于target的1/4,前兩個數之和要不大于一半,前三個不大于3/4。
代碼:
class Solution { public:vector<vector<int> > fourSum(vector<int> &num, int target) {vector<vector<int> > res;if (num.size() < 4) {return res;}sort(num.begin(), num.end());for (int i = 0; i < num.size() - 3;) {if (num[i] * 4 > target)break;for (int j = i + 1; j < num.size() - 2;) {int sumij = num[i] + num[j];if (sumij * 2 > target)break;for (int k = j + 1; k < num.size() - 1;) {int sumijk = sumij + num[k];if (sumijk * 4 > target * 3)break;for (int n = k + 1; n < num.size();) {int sumijkn = sumijk + num[n];if (sumijkn > target)break;if (sumijk + num[n] == target) {vector<int> tmp_res = {num[i], num[j], num[k], num[n]};res.push_back(tmp_res);break;}while (++n < num.size() && num[n] == num[n - 1]){}}while (++k < num.size() - 1 && num[k] == num[k - 1]){}}while (++j < num.size() - 2 && num[j] == num[j - 1]){}}while (++i < num.size() - 3 && num[i] == num[i - 1]){}}return res;} };性能好了一些:
2.4? 我的第四版解法
思路:
其實是看了討論,發現最后兩個數可以通過雙指針查找。
代碼:
class Solution { public:vector<vector<int> > fourSum(vector<int> &num, int target) {vector<vector<int> > res;if (num.size() < 4) {return res;}sort(num.begin(), num.end());int n = num.size();for (int i = 0; i < n - 3;) {if (num[i] * 4 > target)break;for (int j = i + 1; j < n - 2;) {int sumij = num[i] + num[j];if (sumij * 2 > target)break;int l = j + 1;int r = n - 1;int target_sum = target - sumij;while (l < r) {int sumlr = num[l] + num[r];if (sumlr < target_sum) {while (++l < r && num[l] == num[l - 1]){}}if (sumlr == target_sum) {vector<int> tmp_res;tmp_res.push_back(num[i]);tmp_res.push_back(num[j]);tmp_res.push_back(num[l]);tmp_res.push_back(num[r]);res.push_back(tmp_res);while (++l < r && num[l] == num[l - 1]){}while (--r > l && num[r] == num[r + 1]){}}if (sumlr > target_sum) {while (--r > l && num[r] == num[r + 1]){}}}while (++j < num.size() - 2 && num[j] == num[j - 1]){}}while (++i < num.size() - 3 && num[i] == num[i - 1]){}}return res;} };最終性能還湊活:
總結
以上是生活随笔為你收集整理的leetcode 18 --- 4sum的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 类常量用法,php类常量用法实例
- 下一篇: leetcode 142 --- lin