題目: 傳入陣列A和整數S，寫出C++函數從A找三個數字加總為S的組合。
答案: 傳入陣列A和整數S，寫出C++函數從A找三個數字加總為S的組合。  這題可以對應到Leetcode 的 3sum 以及 3sum Closest 兩題  https://leetcode.com/problems/3sum/  https://leetcode.com/problems/3sum-closest/  假設要找的組合不能有重複的，先排序好陣列後會比較好做  第一種作法是排序好後開三層迴圈直接暴力搜尋(Brute Force)  ```cpp  vector<vector<int>> threeSum(vector<int> &nums, int target) { // Brute Force      if (nums.empty() || nums.size() < 3) // 不到三個數字，沒有答案        return {};      int n = nums.size();      sort(nums.begin(), nums.end()); // 先排序好 平均：O(nlgn)，最差：O(n^2)      vector<vector<int>> ret;      for (int i = 0; i < n - 2; i++) {        if (i == 0 || nums[i] != nums[i - 1]) { // 去掉重複的數字          for (int j = i + 1; j < n - 1; j++) {            if (j == i + 1 || nums[j] != nums[j - 1]) {              for (int k = j + 1; k < n; k++) {                if (k == j + 1 || nums[k] != nums[k - 1]) {                  if (nums[i] + nums[j] + nums[k] == target) {                    ret.push_back({nums[i], nums[j], nums[k]});                  }                }              }            }          }        }      }      return ret;    }  ```  時間複雜度為   第二種作法沿用第一種，但使用hash table輔助搜尋，先將所有元素放入hash table，然後暴力枚舉取兩數，假設叫 ，那麼就可以直接用  的時間看 是否有在hash table裡，比直接暴力搜尋還快一個N  ```cpp  vector<vector<int>> threeSum2(vector<int> &nums,                                  int target) { // hash table      if (nums.empty() || nums.size() < 3)        return {};      int n = nums.size();      sort(nums.begin(), nums.end());      vector<vector<int>> ret;      unordered_map<int, int> mp; // hash table      for (int i = 0; i < n; i++) {        mp[nums[i]] = i;      }      for (int i = 0; i < n - 2; i++) {        if (i == 0 || nums[i] != nums[i - 1]) { // 去掉重複的數字          for (int j = i + 1; j < n - 1; j++) {            if (j == i + 1 || nums[j] != nums[j - 1]) {              int t = target - nums[i] - nums[j];              if (mp.find(t) != mp.end() && mp[t] > j) { // 找到且不重複                ret.push_back({nums[i], nums[j], t});              }            }          }        }      }      return ret;    }  ```  時間複雜度為   第三種作法使用 Two Pointers(雙指針)，排序後先固定好陣列中一個數，接著定好左右界()，如果  比目標還大，表示需要取更小的值，右界要往左移動，反之如果比目標小，表示需要取更大的值，左界往右移動，接著只要陣列的每個數字都固定一次(  )，接著雙指針跑一遍 () 就能找出所有組合，加上排序複雜度最差情況是 ，總複雜度   ```cpp  vector<vector<int>> threeSum3(vector<int> &nums,                                  int target) { // Two Pointers, O(n^2)      if (nums.empty() || nums.size() < 3)        return {};      int n = nums.size();      sort(nums.begin(), nums.end());      vector<vector<int>> ret;      for (int i = 0; i < n - 2; i++) {        if (i == 0 || nums[i] != nums[i - 1]) {          int l = i + 1, r = n - 1;          while (l < r) {            if (nums[i] + nums[l] + nums[r] == target) {              ret.push_back({nums[i], nums[l], nums[r]});              while (l < r && nums[l] == nums[l + 1]) // 去掉重複的數字                l++;              while (l < r && nums[r] == nums[r - 1])                r--;              l++;              r--;            } else if (nums[i] + nums[l] + nums[r] < target) {              l++;            } else              r--;          }        }      }      return ret;    }  ```  最後我隨機生一筆 N = 1000 的測資並測量執行時間，得到以下結果(編譯器為 g++ (MinGW-W64), C++11)  Brute Force : 0.712229 Hash table : 0.024005 Two Pointers : 0.004116  (單位：秒)  附檔為完整測試程式碼以及測資
評論: 作法完整且說明十分詳細 Excellent!