vector<int> twoSum(vector<int>& nums, int target) {
// 先對數組排序
sort(nums.begin(), nums.end());
// 左右指針
int lo = 0, hi = nums.size() - 1;
while (lo < hi) {
int sum = nums[lo] + nums[hi];
// 根據 sum 和 target 的比較,移動左右指針
if (sum < target) {
lo++;
} else if (sum > target) {
hi--;
} else if (sum == target) {
return {nums[lo], nums[hi]};
}
}
return {};
}
vector<vector<int>> twoSumTarget(vector<int>& nums, int target);
vector<vector<int>> twoSumTarget(vector<int>& nums, int target {
// 先對數組排序
sort(nums.begin(), nums.end());
vector<vector<int>> res;
int lo = 0, hi = nums.size() - 1;
while (lo < hi) {
int sum = nums[lo] + nums[hi];
// 根據 sum 和 target 的比較,移動左右指針
if (sum < target) lo++;
else if (sum > target) hi--;
else {
res.push_back({lo, hi});
lo++; hi--;
}
}
return res;
}
while (lo < hi) {
int sum = nums[lo] + nums[hi];
// 記錄索引 lo 和 hi 最初對應的值
int left = nums[lo], right = nums[hi];
if (sum < target) lo++;
else if (sum > target) hi--;
else {
res.push_back({left, right});
// 跳過所有重複的元素
while (lo < hi && nums[lo] == left) lo++;
while (lo < hi && nums[hi] == right) hi--;
}
}
vector<vector<int>> twoSumTarget(vector<int>& nums, int target) {
// nums 數組必須有序
sort(nums.begin(), nums.end());
int lo = 0, hi = nums.size() - 1;
vector<vector<int>> res;
while (lo < hi) {
int sum = nums[lo] + nums[hi];
int left = nums[lo], right = nums[hi];
if (sum < target) {
while (lo < hi && nums[lo] == left) lo++;
} else if (sum > target) {
while (lo < hi && nums[hi] == right) hi--;
} else {
res.push_back({left, right});
while (lo < hi && nums[lo] == left) lo++;
while (lo < hi && nums[hi] == right) hi--;
}
}
return res;
}
vector<vector<int>> threeSum(vector<int>& nums);
vector<vector<int>> threeSum(vector<int>& nums) {
// 求和為 0 的三元組
return threeSumTarget(nums, 0);
}
vector<vector<int>> threeSumTarget(vector<int>& nums, int target) {
// 輸入數組 nums,返回所有和為 target 的三元組
}
/* 從 nums[start] 開始,計算有序數組
* nums 中所有和為 target 的二元組 */
vector<vector<int>> twoSumTarget(
vector<int>& nums, int start, int target) {
// 左指針改為從 start 開始,其他不變
int lo = start, hi = nums.size() - 1;
vector<vector<int>> res;
while (lo < hi) {
...
}
return res;
}
/* 計算數組 nums 中所有和為 target 的三元組 */
vector<vector<int>> threeSumTarget(vector<int>& nums, int target) {
// 數組得排個序
sort(nums.begin(), nums.end());
int n = nums.size();
vector<vector<int>> res;
// 窮舉 threeSum 的第一個數
for (int i = 0; i < n; i++) {
// 對 target - nums[i] 計算 twoSum
vector<vector<int>>
tuples = twoSumTarget(nums, i + 1, target - nums[i]);
// 如果存在滿足條件的二元組,再加上 nums[i] 就是結果三元組
for (vector<int>& tuple : tuples) {
tuple.push_back(nums[i]);
res.push_back(tuple);
}
// 跳過第一個數字重複的情況,否則會出現重複結果
while (i < n - 1 && nums[i] == nums[i + 1]) i++;
}
return res;
}
vector<vector<int>> fourSum(vector<int>& nums, int target);
vector<vector<int>> fourSum(vector<int>& nums, int target) {
// 數組需要排序
sort(nums.begin(), nums.end());
int n = nums.size();
vector<vector<int>> res;
// 窮舉 fourSum 的第一個數
for (int i = 0; i < n; i++) {
// 對 target - nums[i] 計算 threeSum
vector<vector<int>>
triples = threeSumTarget(nums, i + 1, target - nums[i]);
// 如果存在滿足條件的三元組,再加上 nums[i] 就是結果四元組
for (vector<int>& triple : triples) {
triple.push_back(nums[i]);
res.push_back(triple);
}
// fourSum 的第一個數不能重複
while (i < n - 1 && nums[i] == nums[i + 1]) i++;
}
return res;
}
/* 從 nums[start] 開始,計算有序數組
* nums 中所有和為 target 的三元組 */
vector<vector<int>>
threeSumTarget(vector<int>& nums, int start, int target) {
int n = nums.size();
vector<vector<int>> res;
// i 從 start 開始窮舉,其他都不變
for (int i = start; i < n; i++) {
...
}
return res;
/* 注意:調用這個函數之前一定要先給 nums 排序 */
vector<vector<int>> nSumTarget(
vector<int>& nums, int n, int start, int target) {
int sz = nums.size();
vector<vector<int>> res;
// 至少是 2Sum,且數組大小不應該小於 n
if (n < 2 || sz < n) return res;
// 2Sum 是 base case
if (n == 2) {
// 雙指針那一套操作
int lo = start, hi = sz - 1;
while (lo < hi) {
int sum = nums[lo] + nums[hi];
int left = nums[lo], right = nums[hi];
if (sum < target) {
while (lo < hi && nums[lo] == left) lo++;
} else if (sum > target) {
while (lo < hi && nums[hi] == right) hi--;
} else {
res.push_back({left, right});
while (lo < hi && nums[lo] == left) lo++;
while (lo < hi && nums[hi] == right) hi--;
}
}
} else {
// n > 2 時,遞歸計算 (n-1)Sum 的結果
for (int i = start; i < sz; i++) {
vector<vector<int>>
sub = nSumTarget(nums, n - 1, i + 1, target - nums[i]);
for (vector<int>& arr : sub) {
// (n-1)Sum 加上 nums[i] 就是 nSum
arr.push_back(nums[i]);
res.push_back(arr);
}
while (i < sz - 1 && nums[i] == nums[i + 1]) i++;
}
}
return res;
}
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
// n 為 4,從 nums[0] 開始計算和為 target 的四元組
return nSumTarget(nums, 4, 0, target);
}
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
// n 為 3,從 nums[0] 開始計算和為 0 的三元組
return nSumTarget(nums, 3, 0, 0);
}