返回

探索三数之和:算法Hot100系列解密!

前端

三数之和:踏上算法进阶之路

欢迎来到算法Hot100系列!今天,我们一起探索激动人心的三数之和问题,踏上算法进阶之路。准备好了吗?那就出发吧!

三数之和:概念剖析

三数之和问题看似简单,但蕴藏着丰富的算法知识。给定一个整数数组nums,找出所有满足a + b + c = 0的三元组(a, b, c),其中abc均来自nums

比如,对于nums = [-1, 0, 1, 2, -1, -4],存在以下三元组:

  • [-1, -1, 2]
  • [-1, 0, 1]

算法策略:双指针法

解决三数之和问题的经典算法策略是双指针法。这种方法利用两个指针从数组的两端向中间移动,动态调整三数之和,高效且巧妙。

具体步骤如下:

  1. 排序数组nums,以方便快速查找目标和。
  2. 固定第一个指针i,代表a
  3. 用两个指针jki + 1n - 1向中间移动,代表bc
  4. 计算三数之和sumsum = nums[i] + nums[j] + nums[k].
  5. 根据sum与目标和0比较,调整jk指针:
    • 如果sum < 0j向右移动(j++),增大三数之和。
    • 如果sum > 0k向左移动(k--),减小三数之和。
    • 如果sum == 0,找到一个三元组,将jk指针向右移动,继续查找重复的三元组。
  6. 重复步骤3-5,直到jk指针相遇。

代码实现:

def threeSum(nums):
    # 排序数组
    nums.sort()

    result = []

    # 固定第一个指针
    for i in range(len(nums) - 2):
        # 跳过重复的a
        if i > 0 and nums[i] == nums[i - 1]:
            continue

        # 设置双指针
        j, k = i + 1, len(nums) - 1

        # 双指针向中间移动
        while j < k:
            # 计算三数之和
            sum = nums[i] + nums[j] + nums[k]

            # 根据sum调整指针
            if sum < 0:
                j += 1
            elif sum > 0:
                k -= 1
            else:
                # 找到三元组,保存结果
                result.append([nums[i], nums[j], nums[k]])

                # 跳过重复的b和c
                while j < k and nums[j] == nums[j + 1]:
                    j += 1
                while j < k and nums[k] == nums[k - 1]:
                    k -= 1

                # 移动指针继续查找
                j += 1
                k -= 1

    return result

时间复杂度分析

双指针法的时间复杂度为O(n^2),其中n是数组nums的长度。这是因为:

  • 排序数组需要O(nlogn)时间。
  • 对于每个元素a(需要n次),使用双指针在剩下的n - 1个元素中查找三元组,需要O(n)时间。

拓展:四数之和及更多

三数之和问题是算法Hot100中的基础问题,类似的拓展问题还有四数之和、五数之和等。这些问题都可以通过双指针法或更高级的算法策略求解。

结语

探索三数之和问题,我们不仅收获了解决问题的算法策略,更领略了算法之美。双指针法巧妙地利用数组有序性,高效地解决了复杂的问题。

算法的学习永无止境,让我们继续前行,在算法Hot100系列中不断探索,解锁更多算法奥秘,成就编程高手之路!

常见问题解答

  1. 三数之和问题有什么实际应用?

三数之和问题在计算机科学和工程领域有着广泛的应用,例如:

  • 物理中的质点碰撞
  • 化学中的反应平衡
  • 经济学中的市场均衡
  1. 双指针法是如何工作的?

双指针法利用两个指针从数组的两端向中间移动,动态调整三数之和,高效且巧妙。当三数之和小于目标和时,右指针向右移动;当三数之和大于目标和时,左指针向左移动。当三数之和等于目标和时,找到一个三元组。

  1. 除了双指针法,还有哪些解决三数之和问题的方法?

除了双指针法,还有其他解决三数之和问题的方法,例如:

  • 哈希表法
  • 排序 + 二分查找法
  1. 三数之和问题的时间复杂度是多少?

双指针法的时间复杂度为O(n^2),其中n是数组nums的长度。

  1. 如何优化双指针法的性能?

优化双指针法的性能可以从以下几个方面入手:

  • 预处理数组,将元素按值分组
  • 使用哈希表存储已经计算过的三数之和
  • 提前终止算法,当找不到满足条件的三元组时