算法day20 三数之和

题目描述

思路:双指针
我们先对nums进行排序,随后设置left与right两个指针跟随for循环遍历的内部迭代。这里的关键就是如何去重。我们在判断时要采取(nums[i]nums[i-1])而非(nums[i]nums[i+1]),因为我们要收集的元组并没有要求内部元素不可以重复,而是要求元组不能重复,所以,我们在采取(nums[i]==nums[i-1])的判断下就可以做到元组的去重,因为每一轮次关于当前nums[i]、nums[left]与nums[right]的符合相加等于0的组合一定都被收集了,循环轮次越向后,元组的组合只能是较前组合的子集或与较前轮次收集的组合完全不同,这里是处理这道题的关键。
代码如下:

vector<vector<int>> threeSum(vector<int> &nums) {
vector<vector<int>> res;
//排序
sort(nums.begin(), nums.end());
int len = nums.size();
int left;
int right;
for (int i = 0;i < len;i++) {
	if (nums[i] > 0) {//排过升序的,若第一个元素都大于0,那么后面的元素也必然大于0
		return res;
	}
    //校验是否重复nums[i]
	if (i > 0 && nums[i] == nums[i - 1]) {
		continue;
	}
	left = i + 1;
	right = len - 1;
	while (left < right) {
		if (nums[i] + nums[left] + nums[right] > 0) {//整体大了的话,让右侧指针收缩
			right--;
		}
		else if (nums[i] + nums[left] + nums[right] < 0) {//整体小了的话,让左侧指针扩张
			left++;
		}
		else {
			res.push_back({ nums[i],nums[left],nums[right] });//相等则收集
			while (left < right && nums[left + 1] == nums[left]) {//去重nums[left]
				left++;
			}
			while (left < right && nums[right] == nums[right - 1]) {//去重nums[right]
				right--;
			}
			right--;
			left++;
		}
	}
}

      return res;}

时间复杂度:O(n^2)
空间复杂度:O(logn(排序栈空间))

END

posted on 2025-04-27 14:50  sakura430  阅读(20)  评论(0)    收藏  举报