Crack LeetCode 之 15. 3Sum

本文详细解析了LeetCode上的3Sum问题,探讨了如何通过封装2Sum问题来解决,介绍了使用夹逼方法处理重复数值的技巧。文章提供了C++和Python的实现代码,并分析了算法的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

3Sum实际上是对2sum的封装。这道题目里会有重复的数,所以2sum使用夹逼的方法求解。算法的时间复杂度是O(n^{2}),空间复杂度是O(n)。以下分别为C++和Python实现。

struct Solution {
	vector<vector<int>> threeSum(vector<int>& num)
	{
		vector<vector<int>> res;
		if (num.empty() || num.size() <= 2)
			return res;

		std::sort(num.begin(), num.end());
		for (int i = (int)num.size() - 1; i >= 2; i--) {
			if (i<num.size() - 1 && num[i] == num[i + 1])
				continue;

			vector<vector<int>> curRes = twoSum(num, i - 1, -num[i]);
			for (int j = 0; j<curRes.size(); j++)
				curRes[j].push_back(num[i]);

			res.insert(res.begin(), curRes.begin(), curRes.end());
		}

		return res;
	}

	vector<vector<int>> twoSum(vector<int>& num, int end, int target)
	{
		vector<vector<int>> res;
		if (num.empty() || num.size() <= 1)
			return res;

		int l = 0;
		int r = end;
		while (l<r) {
			if (num[l] + num[r] == target) {
				vector<int> item;
				item.push_back(num[l]);
				item.push_back(num[r]);
				res.push_back(item);
				l++;
				r--;
				while (l<r&&num[l] == num[l - 1])
					l++;
				while (l<r&&num[r] == num[r + 1])
					r--;
			}
			else if (num[l] + num[r]>target)
				r--;
			else
				l++;
		}

		return res;
	}
};
class Solution:
	def threeSum(self, nums):
		if nums == None or len(nums) < 3:
			return []

		nums.sort()

		res = []
		for i in range(len(nums)-1,0,-1):
			if i < 2:
				break

			if i < (len(nums) - 1) and nums[i] == nums[i+1]:
				continue

			twoSumRes = self.twoSum(nums, i-1, -nums[i])

			for v in twoSumRes:
				v.append(nums[i])
				res.append(v)

		return res

	def twoSum(self, nums, end, target):
		if nums == None or len(nums) < 2:
			return []

		res = []
		l = 0
		r = end
		while l < r :
			if (nums[l] + nums[r]) == target:
				item = []
				item.append(nums[l])
				item.append(nums[r])
				res.append(item)

				l = l + 1
				r = r - 1
				while l < r and nums[l] == nums[l - 1]:
					l = l + 1
				while l < r and nums[r] == nums[r + 1]:
					r = r - 1
			elif (nums[l] + nums[r]) > target:
				r = r - 1
			else:
				l = l + 1

		return res


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值