LeetCode 學習記錄 15. 3Sum
阿新 • • 發佈:2018-12-17
1 題目要求:
Given an array nums
of n integers, are there elements a, b, c in nums
such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
2 解決方法:
類比於sum two,很容易想到將第三個數的相反數作為兩數之和,得到以下程式碼,但是最後一個測試的時間超時。
class TreeSumLess { public: bool operator()(const vector<int>&nums1, const vector<int>&nums2) { int i = 0; while ((i < 3) && (nums1[i] == nums2[i])) i++; if (i == 3) return false; else if (nums1[i] < nums2[i]) return true; else return false; } }; class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> ret; for (int i = 0; i < nums.size(); i++) { unordered_map<int, int> hash; for (int j = i+1; j < nums.size(); j++) { int value = -nums[i] - nums[j]; unordered_map<int, int>::iterator it1 = hash.find(value); if (it1 != hash.end()) { vector<int> temp = {nums[i],nums[j],value}; sort(temp.begin(), temp.end(), less<int>()); ret.push_back(temp); } hash[nums[j]] = value; } } sort(ret.begin(), ret.end(), TreeSumLess()); vector<vector<int>>::iterator pos = unique(ret.begin(), ret.end()); /*ret.resize(distance(ret.begin(), pos));*/ ret.erase(pos,ret.end()); return ret; } };
在特定情況下,例如全0,排序部分刪重過程計算量很大,進一步改進的演算法:
先對向量進行排序,中間可以根據排序特性減少重複的計算。
class Solution { public: vector<vector<int> > threeSum(vector<int> &num) { vector<vector<int> > res; sort(num.begin(), num.end()); for (int i = 0; i < num.size(); i++) { int target = -num[i]; int front = i + 1; int back = num.size() - 1; while (front < back) { int sum = num[front] + num[back]; // Finding answer which start from number num[i] if (sum < target) front++; else if (sum > target) back--; else { vector<int> triplet(3, 0); triplet[0] = num[i]; triplet[1] = num[front]; triplet[2] = num[back]; res.push_back(triplet); // Processing duplicates of Number 2 // Rolling the front pointer to the next different number forwards while (front < back && num[front] == triplet[1]) front++; // Processing duplicates of Number 3 // Rolling the back pointer to the next different number backwards while (front < back && num[back] == triplet[2]) back--; } } // Processing duplicates of Number 1 while (i + 1 < num.size() && num[i + 1] == num[i]) i++; } return res; } };
演算法複雜度O(n2)
空間複雜度O(1)
3 總結
複習了雜湊表、vector中sort erase、unique。排序預處理後的資料,在演算法中會增加順序的特性可以利用。: