【Leetcode 15】3Sum 三數和問題 C++
阿新 • • 發佈:2019-02-13
問題簡述:給定一個數組,找出其中所有不同的三數和等於0的組合。
問題分析:
首先,兩數和問題這樣做。先對陣列中的數進行排序,再設定兩個指標,一個指向頭,一個指向尾。判斷兩數和是否等於想要的數,如果是則在結果集新增這個陣列;如果小了說明左邊指標指向的數小了,因此左指標右移;反之如果大了則右指標左移。
嘗試把三數和問題轉化為兩數和問題:同樣先對陣列排序,設定三個指標p,q,r,p指標指向第一個數x,則q,r要指向陣列中剩餘數中的兩個,並且指向的兩數和為-x,從而轉化為兩數和問題。對p指向第一個數的情況分析完畢後,不可能再有滿足題意且包含x的情況,於是p右移。這樣一直分析到p指向陣列中倒數第三個數的情況。注意跳過所有重複的情況。
經驗:
vector的使用:
①vector<vector<int> >
注意兩個“>”之間要有空格,否則會因為運算子“>>”有歧義;
②vector呼叫建構函式時,可以用vector num(3),用引數3初始化向量中有三個數;
③vector另外一個建構函式,vector num(a, a+len),a為陣列,len為a中元素個數,則將陣列a中的元素構建為向量。sort使用:
①sort在algorithm標頭檔案中
②sort用法,sort(num.begin(), num.end())
程式碼:
(此處參考哈哈的部落格)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution{
public:
vector< vector<int> > threeSum(vector<int> &num) {
vector<int> numSet(3);
vector< vector<int> > r;
// 1.排序
sort(num.begin(), num.end());
int sum;
int len = num.size();
// 2.拿出第一個數,轉化為兩數和問題。注意外層迴圈到倒數第三個數即可
for(int i = 0; i < len-2; i++) {
sum = 0 - num[i];
numSet[0] = num[i];
// 3.兩數和問題
for(int j = i+1, k = len-1; j < k;) {
if(num[j] + num[k] == sum) {
numSet[1] = num[j++];
numSet[2] = num[k--];
r.push_back(numSet);
// 根據題目要求,跳過重複元素
while(j < k && num[j] == num[j-1])
j++;
while(j < k && num[k] == num[k+1])
k--;
}
else if(num[j] + num[k] < sum)
j++;
else
k--;
}
while(i < len-2 && num[i+1] == num[i])
i++;
}
return r;
}
};
int main() {
int a[] = {-2, 13, -5, -4, -7, 8, 0, -9, 6, 7, 0, -4, 2, 1, -2, 4};
int len = sizeof(a) / sizeof(a[0]);
vector<int> num(a, a+len);
Solution s;
vector< vector<int> > result;
result = s.threeSum(num);
// 輸出結果
for(int q = 0; q < result.size(); q++) {
vector<int> x = result[q];
cout << "(";
int t;
for(t = 0; t < x.size()-1; t++) {
cout << x[t] << " ";
}
cout << x[t];
cout << ")" << endl;
}
return 0;
}