LC15-3Sum

https://leetcode.com/problems/3sum/

给一个数组,要求返回其中所有各不相同的三元组,每个三元组中的三个数相加和为0

 

O(N2)解法:

本题是Two Sum的进阶版,枚举数组中的数nums[i],然后用O(N)的复杂度在剩下的数中使用Two Sum找到和为-nums[i]的不同组合

先对nums数组进行快速排序(从小到大),开销O(NlogN)

当我们枚举到nums[i]时,使用双指针滑窗,滑窗左端为i+1,右端为n-1,然后将左右两端的值相加,与-nums[i]进行比较

如果和大于-nums[i],则右端向左移,如果和小于-nums[i],则左端向右移,如果和等于-nums[i],则更新当前结果到答案中,然后左右两端同时向内侧移(滑窗两端都需要更新到不同的值才有可能让结果依然相等)

当左右两端相遇后,nums[i]的结果就都考虑完了,i向右移

滑窗的起点从i+1开始而不是从0开始,是因为nums[i]与前面的数所组成的合法三元组,已经在枚举前面的数的时候考虑过了,所以滑窗从i后面开始是正确的

需要注意的是,因为答案要求所有的三元组各不相同,所以上面所有描述的移动操作,都是移动到下一个不同的值,这样就可以保证枚举出的所有结果都是各不相同的

LC15-3Sum
 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         vector<vector<int>> ret;
 5         sort(nums.begin(),nums.end());
 6         int n = nums.size();
 7         for (int i = 0; i < n; ) {
 8             if (nums[i] > 0) break;
 9             int Target = -nums[i];
10             int low = i + 1, high = n - 1;
11             while (low < high) {
12                 if (nums[low] + nums[high] == Target) {
13                     int ans[3] = { nums[i] ,nums[low] ,nums[high] };
14                     ret.push_back(vector<int>(ans,ans+3));
15 
16                     for (++low; low < n; low++) {
17                         if (nums[low] != nums[low - 1]) {
18                             break;
19                         }
20                     }
21 
22                     for (--high; high >= 0; high--) {
23                         if (nums[high] != nums[high + 1]) {
24                             break;
25                         }
26                     }
27                 }
28                 else if (nums[low] + nums[high] < Target) {
29                     for (++low; low < n; low++) {
30                         if (nums[low] != nums[low - 1]) {
31                             break;
32                         }
33                     }
34                 }
35                 else {
36                     for (--high; high >= 0; high--) {
37                         if (nums[high] != nums[high + 1]) {
38                             break;
39                         }
40                     }
41                 }
42             }
43             for (++i; i < n; i++) {
44                 if (nums[i] != nums[i - 1]) {
45                     break;
46                 }
47             }
48         }
49 
50         return ret;
51     }
52 };
代码

 

上一篇:3Sum


下一篇:[LC] 259. 3Sum Smaller