返回

技巧满载!LeetCode每日一题:四数之和解析指南

前端

前言

在 LeetCode 每日一题的挑战中,“四数之和”无疑是一个备受欢迎的难题。它考察了你的算法思维、数据结构知识以及代码实现能力。本文将为你提供一份全面的指南,一步步剖析“四数之和”问题,并分享各种求解方案,帮助你提升算法技能并征服这个难题。

问题陈述

给定一个包含 n 个整数的数组 nums 和一个目标值 target,请找出数组中所有满足 nums[a] + nums[b] + nums[c] + nums[d] = target 的元组 (a, b, c, d)。

注意:

  • 元组 (a, b, c, d) 中的数字必须唯一,并且 a、b、c 和 d 互不相同。

解决方案

暴力法

最直接的求解方法是采用暴力法。这种方法的思路是枚举数组中所有的四元组,并计算它们的和。如果和等于目标值,则将该四元组加入结果列表中。

def fourSum(nums, target):
    # 排序数组,以便于使用双指针
    nums.sort()

    # 存储结果
    result = []

    # 遍历数组中的每个元素
    for i in range(len(nums)):
        # 跳过重复元素
        if i > 0 and nums[i] == nums[i - 1]:
            continue

        # 设置左右指针
        left, right = i + 1, len(nums) - 1

        # 使用双指针查找其他三个数字
        while left < right:
            # 计算当前四元组的和
            sum = nums[i] + nums[left] + nums[right]

            # 更新指针位置
            if sum < target:
                left += 1
            elif sum > target:
                right -= 1
            # 找到目标和,将四元组添加到结果列表
            else:
                result.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 result

优化后的暴力法

为了优化暴力法,我们可以利用排序数组的特性。由于数组已排序,我们可以使用两个指针从数组的两端开始遍历。如果当前四元组的和大于目标值,则右指针左移;如果小于目标值,则左指针右移;如果等于目标值,则将四元组添加到结果列表中。

def fourSum(nums, target):
    # 排序数组
    nums.sort()

    # 存储结果
    result = []

    # 遍历数组中的每个元素
    for i in range(len(nums)):
        # 跳过重复元素
        if i > 0 and nums[i] == nums[i - 1]:
            continue

        # 设置左右指针
        left, right = i + 1, len(nums) - 1

        # 使用双指针查找其他三个数字
        while left < right:
            # 计算当前四元组的和
            sum = nums[i] + nums[left] + nums[right]

            # 更新指针位置
            if sum < target:
                left += 1
            elif sum > target:
                right -= 1
            # 找到目标和,将四元组添加到结果列表
            else:
                result.append([nums[i], nums[left], nums[right]])

                # 移动指针
                left += 1
                right -= 1

    return result

时间复杂度分析

暴力法和优化后的暴力法的时间复杂度均为 O(n^3),其中 n 为数组 nums 的长度。

代码示例

输入:

nums = [1, 0, -1, 0, -2, 2]
target = 0

输出:

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

总结

通过本文的讲解,相信你已经对 LeetCode 每日一题中的“四数之和”难题有了全面的理解。掌握了上述求解方案,你将能够高效地解决此类问题,提升你的算法思维和代码实现能力。持续练习,不断探索,你将成为算法领域的佼佼者。