[leetcode][two pointers] 3Sum

题目:

Given an array S of n integers, are there elements abc 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)
class Solution {
public:
//时间复杂度是O(nlogn)+O(n^2),所以总的时间复杂度是O(n^2),空间复杂度是O(1)
    vector<vector<int>> threeSum(vector<int>& nums) {
	vector<vector<int> > res;
	if (nums.size() < 3) return res;
	vector<int> oneTriplet(3);
	//排序
	sort(nums.begin(), nums.end());
	//for循环遍历数组,在其后用首尾指针找和为-nums[i]的两个元素,注意去重
	for (int i = 0; i < nums.size() - 2; ++i){
		if (i != 0 && nums[i] == nums[i - 1]) continue;//去重
		int target = -nums[i];
		int left = i + 1;
		int right = nums.size() - 1;
		while (left < right){
			if (left != i + 1 && nums[left] == nums[left - 1]){
				++left;
				continue;
			}
			if (right != nums.size() - 1 && nums[right] == nums[right + 1]){
				--right;
				continue;
			}
			if (nums[left] + nums[right] == target){
				
				oneTriplet[0] = nums[i];
				oneTriplet[1] = nums[left];
				oneTriplet[2] = nums[right];
				res.push_back(oneTriplet);
				++left;
			}
			else if (nums[left] + nums[right] < target) ++left;
			else --right;
		}
	}
	return res;
}
};


下面是用hash的方法找2sum,会TLE


class Solution {
public:
//时间复杂度是O(n*n*logn),空间复杂度是O(n)
vector<vector<int>> threeSum(vector<int>& nums) {
	vector<vector<int> > res;
	if (nums.size() < 3) return res;
	//排序
	sort(nums.begin(), nums.end());
	//for循环遍历数组,找2sum(hash),注意去重
	for (int i = 0; i < nums.size() - 2; ++i){
		if (i != 0 && nums[i] == nums[i - 1]) continue;//去重
		int target = -nums[i];
		set<pair<int, int> > lastTwo;
		if (found2Sum(nums, i + 1, target, lastTwo)){
			vector<int> tmp(3);
			for (set<pair<int, int> >::iterator iter = lastTwo.begin(); iter != lastTwo.end(); ++iter){
				tmp[0] = nums[i];
				tmp[1] = iter->first;
				tmp[2] = iter->second;
				res.push_back(tmp);
			}	
		}
	}
	return res;
}
private:
    bool found2Sum(vector<int> &nums, int start, int target, set<pair<int, int> > &lastTwo){//为了得到无重复的二元组,所以使用set
	if (start >= nums.size() - 1) return false;
	set<int> hashSet;
	hashSet.insert(nums[start]);
	for (int i = start + 1; i < nums.size(); ++i){
		if (hashSet.count(target - nums[i])){//找到
			lastTwo.insert(make_pair(target - nums[i], nums[i]));
		}
		hashSet.insert(nums[i]);
	}
	return lastTwo.size() ? true : false;
}
};


注:

1.本题和2sum不同,2sum要求输出下标,所以不能使用先对数组排序在使用首尾指针来查找,hash更合适。本题要求输出元素值,所以排序+首尾指针更合适(时间和空间效率都更高)

2.注意去重,而且两层都要去重。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值