力扣15. 三数之和 双指针+排序 滑动易懂解法

Posted weixin_43739821

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣15. 三数之和 双指针+排序 滑动易懂解法相关的知识,希望对你有一定的参考价值。

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

提示:

0 <= nums.length <= 3000
-10^5 <= nums[i] <= 10^5

思路:
此题暴力会超时,使用排序+哈希表处理起来会相当麻烦,最佳做法是排序+双指针。
首先为了保证题目要求的不重复,我们将原容器递增排序,首先固定第一个数a,然后在不小于a的数中设立双指针left指向b、right指向c找出剩余俩个满足条件的数,使得每次遍历的三个数满足a<=b<=c。
双指针法设置左右俩个端点不断往内靠近,当三数和为0则添加进返回列表,同时将左右指针各往内移动一位;若三数和小于0,则将左指针往内移动一位,反之移动右指针。滑动过程中全程需要left<right。
其次若a已经大于0,那么b、c肯定大于0,直接结束遍历返回结果。
最后要注意,我们固定第一个数a的时候当下一次循环的a数值不变我们需要跳过此次循环,为什么呢?
我们举个例子,比如有排序好的数列:-2、-2、-1、3、4
第一次固定-2找寻求满足题目的条件三元组有:(-2,-2,4)和(-2,-1,3)
当进行下一次循环时a固定为第二个-2,此时满足条件的三元组是(-2,-1,3),与上一次循环重复了,所以需要跳过,因为在上一次遍历的双指针滑动过程中已经将这个因素考虑进去了,所以直接跳过本次循环,同时双指针滑动同理,当双指针往内滑动的时候,若滑动后的数值与上次一样也需要再滑动一次直到不一样。

vector<vector<int>> threeSum(vector<int>& nums) {
    int n = nums.size();
	vector<vector<int>>sum;
	if (n < 3) return sum;
	sort(nums.begin(), nums.end());
	for (int i = 0; i < n; i++) {
		if (nums[i] > 0) break;
		if (i == 0 || nums[i] != nums[i - 1]) {
			int left = i + 1, right = n - 1;
			while (left < right) {
				if (nums[i] + nums[left] + nums[right] == 0) {
					sum.push_back({ nums[i],nums[left],nums[right] });
					left++;
					while (nums[left] == nums[left - 1]&&left<right) left++;
					right--;
					while (nums[right] == nums[right + 1] && left < right) right--;
				}
				else if (nums[i] + nums[left] + nums[right] > 0) {
					right--;
					while (nums[right] == nums[right + 1] && left < right) right--;
				}
				else {
					left++;
					while (nums[left] == nums[left - 1] && left < right) left++;
				}
			}
		}
	}
	return sum;
    }

以上是关于力扣15. 三数之和 双指针+排序 滑动易懂解法的主要内容,如果未能解决你的问题,请参考以下文章

力扣15. 三数之和

力扣15. 三数之和

最接近的三数之和--力扣

双指针问题复习

leetcode 15. 三数之和(sort+双指针)

三数之和(双指针)