網(wǎng)站怎么推廣網(wǎng)絡(luò)營銷是以什么為基礎(chǔ)
15. 三數(shù)之和
給你一個(gè)整數(shù)數(shù)組
nums
,判斷是否存在三元組[nums[i], nums[j], nums[k]]
滿足i != j
、i != k
且j != k
,同時(shí)還滿足nums[i] + nums[j] + nums[k] == 0
。請(qǐng)你返回所有和為0
且不重復(fù)的三元組。注意:答案中不可以包含重復(fù)的三元組。
示例 1:
輸入:nums = [-1,0,1,2,-1,-4] 輸出:[[-1,-1,2],[-1,0,1]] 解釋: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元組是 [-1,0,1] 和 [-1,-1,2] 。 注意,輸出的順序和三元組的順序并不重要。示例 2:
輸入:nums = [0,1,1] 輸出:[] 解釋:唯一可能的三元組和不為 0 。示例 3:
輸入:nums = [0,0,0] 輸出:[[0,0,0]] 解釋:唯一可能的三元組和為 0 。
首先利用雙指針?biāo)枷脒M(jìn)行尋找合適的三個(gè)數(shù),再利用set進(jìn)行去重。
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n = nums.size();set<vector<int>> res;sort(nums.begin(), nums.end());for(int i = n-1; i > 1; i--){int c = nums[i];int temp = 0-c;int left = 0, right = i-1;while(left < right){if(nums[left] + nums[right] < temp)left++;else if(nums[left] + nums[right] > temp)right--;else{res.insert({nums[left], nums[right], c});left++;}}}vector<vector<int>> ret;for(auto it : res){ret.push_back(it);}return ret;}
};
離譜……………………
對(duì)于去重的方法有進(jìn)一步優(yōu)化
?將c從右向左固定:
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n = nums.size();vector<vector<int>> ret;sort(nums.begin(), nums.end()); 1、排序for(int i = n-1; i > 1; ){int c = nums[i];int temp = 0-c;int left = 0, right = i-1;while(left < right) 2、此處使用雙指針?biāo)枷雥if(nums[left] + nums[right] < temp)left++;else if(nums[left] + nums[right] > temp)right--;else{ret.push_back({nums[left], nums[right], c});int flag = nums[left++];while(left<right && nums[left] == flag) left++; 3、對(duì)于去重操作的優(yōu)化①flag = nums[right--];while(left<right && nums[right] == flag)right--;}}i--; 4、去重的優(yōu)化②while(i>1 && nums[i+1] == nums[i]) // 把whlie寫錯(cuò)成if調(diào)試半天才發(fā)現(xiàn)i--;}return ret;}
};
將c從左向右固定
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n = nums.size();sort(nums.begin(), nums.end()); // 1、排序vector<vector<int>> ret;for(int i = 0; i < n; ){if(nums[i] > 0) break; // 2、作一個(gè)小優(yōu)化,如果左邊數(shù)大于零則無法滿足和為0int left = i+1, right = n-1;int target = -nums[i];while(left < right) // 3、雙指針進(jìn)行尋找{int sum = nums[left] + nums[right];if(sum < target) left++;else if(sum > target) right--;else{ret.push_back({nums[i], nums[left++], nums[right--]});while(left < right && nums[left] == nums[left-1])left++; // 當(dāng)left位置重復(fù)時(shí),left后移while(left < right && nums[right] == nums[right+1])right--; // 當(dāng)right位置重復(fù)時(shí),right左移}}i++;while(i < n && nums[i]==nums[i-1])i++;}return ret;}
};