leetcode-15:3sum 三數之和
阿新 • • 發佈:2018-12-22
題目:
Given an array 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] ] |
給定一個包含 n 個整數的陣列 注意:答案中不可以包含重複的三元組。 例如, 給定陣列 nums = [-1, 0, 1, 2, -1, -4], 滿足要求的三元組集合為: [ [-1, 0, 1], [-1, -1, 2] ] |
思路:先對原陣列排序,然後遍歷排序後的陣列。在迴圈內可以做如下優化:1.若當前遍歷的 數是正數,就 break;因為當前陣列已經是有序,後面的數字肯定是正數,和就不會是0,;2.加上重複跳過功能,,若第2個數與前面數相等則跳過。
我們使target=0-遍歷過的數,然後檢視剩下的元素是否為target。我們使用兩個指標,i從當前遍歷元素下一個開始從前往後,j從後往前,若兩個數之和剛好為target,將當前元素,i和j一起放入ret,然後兩個指標跳過重複元素。若兩數之和小於target,則左指標向右移動一位,若大於target,j向左移動一位。
注意:1.若vector.size()需要用到兩次以上,最好定義一個變數來儲存vector的size(),這會省時間。
2.不要在迴圈體內定義變數,這也會造成浪費時間。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ret;
sort(nums.begin(),nums.end());
if(nums.empty()) return {};
int len=nums.size(),i,j,target;
for(int k=0;k<len;++k)
{
if(nums[k]>0) break;
if(k>0 && nums[k]==nums[k-1]) continue;
i=k+1;
j=len-1;
target = 0-nums[k];
while(i<j)
{
if(nums[i]+nums[j]==target)
{
ret.push_back({nums[k],nums[i],nums[j]});
while(i<j && nums[j]==nums[j-1]) j--;
while(i<j && nums[i]==nums[i+1]) i++;
j--;i++;
}else if(nums[i]+nums[j]<target) i++;
else j--;
}
}
return ret;
}
};
參考: