LeetCode算法 —— 三数之和(排序 / 双指针原理)

相关文章如下所示:
LeetCode算法 —— 最接近的三数之和(排序 / 双指针原理)

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

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

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]


为何排序:将数组排序好之后,可以大大的提高算法的效率,利用双指针原理进行工作,可以减少大量的重复判断
为何使用双指针:使用双指针可以将复杂度降到O(n),大大的提高效率 . . .

代码如下所示:

class Solution {
public:
	vector<vector<int>> threeSum(vector<int>& nums) {

		vector<vector<int>> retArr;

		if (nums.size() < 3) return retArr;
		if (nums.size() == 3) {
			if (nums[0] + nums[1] + nums[2] == 0)
				retArr.push_back(nums);
			return retArr;
		}

		// 排序,性能优化(双指针操作基于此原理)
		sort(nums.begin(), nums.end());

		int nSize = nums.size();
		for (size_t i = 0; i < nSize; i++) {
		
			// 跳过重复 前面的数已经把可能性测试过了
			if (i > 0 && nums[i] == nums[i - 1]) continue;

			// i + 1 跳过重复,前面的数应该都和当前的数比较过了
			auto result = twoSum(nums, i + 1, nSize - 1, -nums[i], nums[i]);
			
			retArr.insert(retArr.end(), result.begin(), result.end());
		}


		return retArr;
	}

private:
	vector<vector<int>> twoSum(vector<int>& nums, int start, int end, int target, int value) {
		vector<vector<int>> answer;

		// 双指针原理
		while (start < end) {
			int sum = nums[start] + nums[end];

			if (sum == target) {
				answer.push_back({ value,nums[start],nums[end] });

				// 该数已经判断过了,跳过该数
				while (start < end && nums[start] == nums[start + 1]) {
					++start;
				}
				++start;

				while (start < end && nums[end] == nums[end - 1]) {
					--end;
				}
				--end;
			}
			else if (sum < target) {
				++start;
			}
			else {
				--end;
			}
		}

		return answer;
	}
};

三处代码解释:

1)第一处:
在这里插入图片描述
如果 nums[i] == nums[i - 1],那么则进行下次循环,因为此数组是排序好的,所以先将 nums[i - 1] 的所有可能性已经判断好了,而 nums[i] == nums[i - 1],所以 nums[i] 就不需要判断了,直接跳过就好 . . .

.

2)第二处:
在这里插入图片描述
为什么从 i + 1开始,而不是 0?如果每次从0开始,会有大量重复的数据,从 i + 1开始,每次的范围都不一样,后面的都比前面的大,前面都已经判断过了,所以不需要在在区域内重新的判断 . . .

.

3)第三处:
在这里插入图片描述
nums[start] 和 nums[end] 已经判断过了,所以下次判断就不需要了,循环表示的意义是过滤掉所有一样的值,比如一堆数据 5 5 5 5 6,第一个5已经判断过了,所以下次不允许重复,则直接判断到 6的地方 . . .

.
.
.


猜你喜欢

转载自blog.csdn.net/weixin_42100963/article/details/107397977