1. 程式人生 > >【Leetcode 15】3Sum 三數和問題 C++

【Leetcode 15】3Sum 三數和問題 C++

問題簡述:給定一個數組,找出其中所有不同的三數和等於0的組合。

問題分析:
首先,兩數和問題這樣做。先對陣列中的數進行排序,再設定兩個指標,一個指向頭,一個指向尾。判斷兩數和是否等於想要的數,如果是則在結果集新增這個陣列;如果小了說明左邊指標指向的數小了,因此左指標右移;反之如果大了則右指標左移。
嘗試把三數和問題轉化為兩數和問題:同樣先對陣列排序,設定三個指標p,q,r,p指標指向第一個數x,則q,r要指向陣列中剩餘數中的兩個,並且指向的兩數和為-x,從而轉化為兩數和問題。對p指向第一個數的情況分析完畢後,不可能再有滿足題意且包含x的情況,於是p右移。這樣一直分析到p指向陣列中倒數第三個數的情況。注意跳過所有重複的情況。

經驗:

  1. vector的使用:
    vector<vector<int> >注意兩個“>”之間要有空格,否則會因為運算子“>>”有歧義;
    ②vector呼叫建構函式時,可以用vector num(3),用引數3初始化向量中有三個數;
    ③vector另外一個建構函式,vector num(a, a+len),a為陣列,len為a中元素個數,則將陣列a中的元素構建為向量。

  2. 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; }