19
04/2015
[LeetCode] 3Sum
3Sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4},
A solution set is:
(-1, 0, 1)
(-1, -1, 2)解题思路:
1、网上有说不可以用hash表的方法计算,我想了一下,其实也是可以的,首先给元素排序,然后用map记录每个元素最大的下标。整个思想大致为,首先找到第一个元素,再找到第二个元素,然后利用hash表找到第三个元素。这道题一个难点是可能会有多个相同的结果,如何去重问题?注意到代码中若相同,则continue,这样便能去重了。
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
//题目转化为其中两个数是的和等于第三个数的相反数
vector<vector<int>> result;
int len = num.size();
if(len<3){
return result;
}
std::sort(num.begin(), num.end());
map<int, int> numToMaxIndex;
for(int i=len-1; i>=0; i--){
if(i<len-1&&num[i]==num[i+1]){
continue;
}
numToMaxIndex[num[i]]=i;
}
for(int i=0; i<len; i++){
if(i>0&&num[i]==num[i-1]){
continue;
}
for(int j=i+1; j<len; j++){
if(j>i+1&&num[j]==num[j-1]){
continue;
}
int thirdNum = -(num[i]+num[j]);
if(thirdNum<num[j]){
continue;
}
map<int, int>::iterator it=numToMaxIndex.find(thirdNum);
if(it!=numToMaxIndex.end()&&it->second>j){
vector<int> triple({num[i], num[j], num[it->second]});
result.push_back(triple);
}
}
}
return result;
}
};2、另一种就是网上通用的两边夹的办法了。如下所示。
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
int n = num.size();
sort(num.begin(), num.end());
vector<vector<int> > res;
for(int i = 0; i < n-2; i++)
{
if(i > 0 && num[i] == num[i-1])continue;//重复的元素不用计算
int target2 = 0 - num[i];
twoSum(num, i+1, target2, res);
}
return res;
}
void twoSum(vector<int> &sortedNum, int start, int target, vector<vector<int> >&res)
{
int head = start, tail = sortedNum.size() - 1;
while(head < tail)
{
int tmp = sortedNum[head] + sortedNum[tail];
if(tmp < target)
head++;
else if(tmp > target)
tail--;
else
{
res.push_back(vector<int>{sortedNum[start-1], sortedNum[head], sortedNum[tail]});
//为了防止出现重复的二元组,使结果等于target
int k = head+1;
while(k < tail && sortedNum[k] == sortedNum[head])k++;
head = k;
k = tail-1;
while(k > head && sortedNum[k] == sortedNum[tail])k--;
tail = k;
}
}
}
};二次刷题(2015-08-18)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
int len = nums.size();
if(len < 3){
return result;
}
std::sort(nums.begin(), nums.end());
map<int, int> mapToIndex; //值与最大下标的映射关系,防止取本身
for(int i=0; i<len; i++){
mapToIndex[nums[i]] = i;
}
for(int i=0; i<len; i++){
if(i>0 && nums[i-1] == nums[i]){
continue;
}
for(int j=i+1; j<len; j++){
if(j>i+1 && nums[j-1]==nums[j]){
continue;
}
int num = - (nums[i] + nums[j]);
map<int, int>::iterator it = mapToIndex.find(num);
if(it != mapToIndex.end() && it->second > j){
result.push_back(vector<int>({nums[i], nums[j], it->first}));
}
}
}
return result;
}
};转载请注明:康瑞部落 » [LeetCode] 3Sum

0 条评论