15. 三数之和

101 阅读3分钟

题目

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

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

示例 1:

输入: nums = [-1,0,1,2,-1,-4]
输出: [[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1][-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入: nums = [0,1,1]
输出: []
解释: 唯一可能的三元组和不为 0 。

示例 3:

输入: nums = [0,0,0]
输出: [[0,0,0]]
解释: 唯一可能的三元组和为 0

  提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

题目解析

算法:

这个问题的关键在于如何高效地找出所有符合条件的三元组,同时避免重复。解决方案通常采用的是“排序加双指针”方法。这是解决这类数值组合问题的一种有效策略,特别是当我们需要在数组中寻找符合特定条件的元素组合时。

方法:

  1. 排序: 对数组进行排序,使我们能够应用双指针技术,并有效地避免重复元素的处理。
  2. 双指针遍历: 对于每个元素,我们在其之后的数组部分使用两个指针来寻找两个数字,使得这三个数的和为零。
  3. 跳过重复元素: 在遍历和双指针移动过程中,注意跳过重复的元素,以避免重复的三元组。
class Solution:
    def threeSum(self, nums):
        nums.sort()
        n, res = len(nums), []

        for i in range(n):
            if nums[i] > 0: break  # 优化1: 提前终止循环
            if i > 0 and nums[i] == nums[i-1]: continue  # 优化2: 跳过重复元素

            left, right = i + 1, n - 1
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total < 0:
                    left += 1
                elif total > 0:
                    right -= 1
                else:
                    res.append([nums[i], nums[left], nums[right]])
                    while left < right and nums[left] == nums[left + 1]: left += 1
                    while left < right and nums[right] == nums[right - 1]: right -= 1
                    left += 1
                    right -= 1

        return res

执行

image.png

总结

“三数之和”问题是一种典型的组合求和问题,通常出现在需要从数组中找到符合特定条件的多个数字的情况。这种类型的问题适合使用双指针法,尤其是当我们需要找到两个数的组合来满足某种条件时(例如和为特定值)。在这个问题中,我们通过排序数组并使用双指针来减少不必要的搜索,并有效地跳过重复的元素。

这个问题的核心在于如何高效地处理数组中的数值组合。它不仅考验对基本排序和搜索算法的掌握,也考验对双指针技巧的应用能力,以及如何在保证效率的同时避免重复计算。尽管“三数之和”问题的最优解法在时间复杂度上为 O(n^2),但通过这种优化方法,我们可以在实际应用中取得较好的性能表现,特别是在处理大型数据集时。

这个问题也提醒我们,在面对算法问题时,选择合适的方法和优化策略是至关重要的。理解问题的本质,选择适当的数据结构和算法,可以显著提升解决问题

题目链接

三数之和