1. 程式人生 > >Array + two points leetcode.18 - 4Sum

Array + two points leetcode.18 - 4Sum

while urn 排序 pub ger arr 代碼 思路 array

題面

Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b+ c + d = target? Find all unique quadruplets in the array which gives the sum of target.

給定無序數組,找到和為target的不重復長度為4的子序列

樣例

1. Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]
2. Given array nums = [0, 0, 0, 0], and target = 0.
solution set is:
[
  [0, 0, 0, 0]  
]
note: This example need to think specially!
3. Given array nums = [-3, -3, -3, 2, 2, 2,0, 0, 0, 3, 3, 3], and target = 0.
solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]
Note: How to deal with the duplicate quadruplets ?

思路(這裏是4個數的和為target,我們之前不是做過3個數的嗎?Refer this one 正好可以用上)

1. 升序排序(sort即可)

2. 不可避免地要遍歷數組(i)

3. 借鑒leetcode-15中的三個數的和,我們如法炮制,搜索剩下的三個數(j = i+1, l=j+1, r = size()-1);對參數有疑惑的話,看下面代碼。

時間復雜度:O(n3),暴力的話應該會超時,沒試!

這題裏面尤其要註意避免重復

源碼

 1 class Solution {
 2 public:
 3     vector<vector<int>> fourSum(vector<int
>& nums, int target) { 4 vector<vector<int>> res; 5 int len = nums.size(); 6 if(len < 4) 7 return res; 8 9 sort(nums.begin(), nums.end()); 10 for(int i=0; i<=len-4; i++) 11 { 12 while(i>0 && i<=len-4 && nums[i]==nums[i-1]) 13 i++;//消除i的重復 14 for(int j=i+1; j<=len-3; j++) 15 { 16 while(j>i+1 && j<=len-3 && nums[j]==nums[j-1]) 17 j++;//消除j的重復 18 int l=j+1, r=len-1; 19 while(l < r) 20 { 21 int sum = nums[i] + nums[j] + nums[l] + nums[r]; 22 if(sum > target) 23 r--; 24 else if(sum < target) 25 l++; 26 else 27 { 28 res.push_back(vector<int> {nums[i], nums[j], nums[l], nums[r]}); 29 while(l<r && nums[l]==nums[l+1]) l++;//消除l的重復 30 while(l<r && nums[r]==nums[r-1]) r--;//消除r的重復 31 l++; r--; 32 } 33 } 34 } 35 } 36 return res; 37 } 38 };

如果對消除重復有疑問的童鞋,請留言, 或者自行把example 3 手推一遍就明白了。

Array + two points leetcode.18 - 4Sum