您的位置:首页 > 其它

[leetcode] 18. 4Sum 解题报告

2016-01-04 05:07 344 查看
题目链接:https://leetcode.com/problems/4sum/

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

Note:

Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
The solution set must not contain duplicate quadruplets.

For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

A solution set is:
(-1,  0, 0, 1)
(-2, -1, 1, 2)
(-2,  0, 0, 2)


思路:一种最直接的方式是DFS暴力搜索,时间复杂度是O(n^4),这种方式肯定超时,所以我们需要寻找其他的方法。

枚举第一个和第二个数,然后寻找第三第四个数的问题就变成了2sum的问题。

在2sum问题中我们的目标是找到两个数的和等于一个给定的数,所以我们要用到左右指针,left = 0, right = len-1;因为使用左右指针需要数组有序,因此我们要首先对数组进行排序。

而左右指针的移动规律是:

1. 如果当前nums[left] + nums[right] > target,说明我们要想让其和等于target,则需要让right指针左移一位,因为当前和太大了

2. 如果当前nums[left] + nums[right] < target,说明我们要想让其和等于target,则需要让left指针右移一位,因为当前和太小了

3. 如果当前nums[left] + nums[right] = target,则可以保存结果,左右指针都移动一次。然后需要注意的就是去重,如果nums[left+1] = nums[left]或nums[right-1]==nums[right],

则必须跳过这些值,因为这些方案都已经搜索过了。

恩,思路大概就是这些,4sum比2sum多了一些第一个和第二个数也要去重的步骤。这种时间复杂度是O(n^3)。

代码如下:

class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
if(nums.size() < 4) return vector<vector<int>>();
sort(nums.begin(), nums.end());
vector<vector<int>> result;
for(int i =0; i< nums.size()-3; i++)
{
for(int j= i+1; j < nums.size()-2; j++)
{
int left = j+1, right = nums.size()-1;
while(left < right)
{
int val = nums[i] + nums[j] + nums[left] + nums[right];
if(val == target)
{
vector<int> vec{ nums[i], nums[j], nums[left], nums[right]};
result.push_back(vec);
while(left < right && nums[left] == nums[left+1]) left++;
while(left < right && nums[right] == nums[right-1]) right--;
left++, right--;
}
else val < target?++left:--right;
}
while(nums[j] == nums[j+1]) j++;
}
while(nums[i] == nums[i+1]) i++;
}
return result;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: