Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2)
問題:求數組中,所有和為0 的三個元素。
解題思路:
自己想了一個解法,但是扔上去超時了,然后在網上看到使用雙指針的算法,理解后,把這道題解決了。
第一步,對數組排序。
第二步,
分析1:對於元素 S[i] , 最后的答案可以分為兩種,包含 S[i] 的,和不包含 S[i] 的。當包含 S[i] 的情況都找到后,后續就可以不用在考慮 S[i] 。
對於 S[i] , l = i+1, r = len-1 。若 s[i] + S[l] + S[r] == 0, 則為原問題的一個解。
- 當 S[i] + S[l] > -S[r] 時,則 r--
- 當 S[i] + S[l] < -S[r] 時,則 l++
- 當 S[i] + S[i] = -S[r] 時, 表示是原問題的一個解,則 l++, r--;
第三步,性能優化。同樣根據分析1,若 S[i] == S[i+1],可以跳過。
vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; std::sort(nums.begin(), nums.end()); map<string, vector<int>> key_res; for (int i = 0 ; i < (int)nums.size(); i++) { // star 剪枝優化 if (i >= 1) { while (nums[i] == nums[i-1]) { i++; continue; } } // end 剪枝優化 int l = i+1; int r = (int)nums.size()-1; while (l < r) { if (nums[l] + nums[r] > -nums[i]) { r--; continue; } else if (nums[l] + nums[r] < -nums[i]){ l++; }else{ string k = to_string(nums[i]) + "," + to_string(nums[l]) + "," + to_string(nums[r]); vector<int> tmp = {nums[i], nums[l] , nums[r]}; key_res[k] = tmp; l++; r--; } } } map<string, vector<int>>::iterator m_iter; for (m_iter = key_res.begin(); m_iter != key_res.end(); m_iter++) { res.push_back(m_iter->second); } return res; }