返回

智能解析 LeetCode 209:寻找长度最小的连续子数组满足特定和

前端

简介

LeetCode 209 题旨在寻找一个连续子数组,满足其元素之和大于或等于一个给定的目标值,同时还应满足长度最小的条件。这道题是 LeetCode 上的经典题目之一,要求我们充分利用动态规划和滑动窗口算法技巧来优化求解过程,从而以高效的方式找到所需的连续子数组。

问题解析

LeetCode 209 题给定一个包含 n 个正整数的数组 nums 和一个正整数 target,要求我们找到满足 sum(nums[i], ..., nums[j]) >= target 的连续子数组 [nums[i], ..., nums[j]],其中 ij 为数组下标,且 i <= j。目标是找到满足条件的子数组中,其长度 j - i + 1 最小。

算法思路

要解决 LeetCode 209 题,我们可以结合动态规划和滑动窗口这两种算法技巧来优化求解过程,具体步骤如下:

1. 初始化

  • 定义一个动态规划表 dp[i],其中 dp[i] 表示以 nums[i] 结尾的连续子数组的最小长度,满足 sum(nums[i], ..., nums[j]) >= target
  • dp[0] 初始化为正无穷,因为空子数组无法满足和大于或等于 target 的条件。

2. 动态规划

  • 对于 i1n-1,执行以下步骤:
    • 首先将 dp[i] 初始化为正无穷。
    • 接着,对于 j0i-1,执行以下步骤:
      • 计算 sumnums[j] + nums[j+1] + ... + nums[i]
      • 如果 sum >= target,则将 dp[i] 更新为 min(dp[i], dp[j] + 1)

3. 获取结果

  • 动态规划完成后,dp[n-1] 即为满足条件的连续子数组的最小长度。
  • 使用滑动窗口来找到满足条件的子数组。滑动窗口的左边界为 i,右边界为 j,如果 sum(nums[i], ..., nums[j]) >= target,则滑动窗口向右移动,直至 sum(nums[i], ..., nums[j]) < target,此时子数组 [nums[i], ..., nums[j]] 即为满足条件的连续子数组。

代码实现

def minSubArrayLen(target: int, nums: List[int]) -> int:
    """
    Finds the minimum length of a contiguous subarray that sums to a given target.

    Args:
        target (int): The target sum.
        nums (List[int]): The list of numbers to search.

    Returns:
        int: The minimum length of a contiguous subarray that sums to target, or 0 if no such subarray exists.
    """
    n = len(nums)
    # Initialize the dp table.
    dp = [float('inf') for _ in range(n)]
    dp[0] = 1 if nums[0] >= target else 0

    # Populate the dp table.
    for i in range(1, n):
        dp[i] = dp[i-1]  # Default: the minimum length of the subarray ending at i is the same as that of i-1
        for j in range(i):
            if sum(nums[j:i+1]) >= target:
                dp[i] = min(dp[i], dp[j] + 1)

    # Check if a valid subarray exists.
    if dp[n-1] == float('inf'):
        return 0

    # Find the subarray with the minimum length.
    min_len = dp[n-1]
    left, right = 0, 0
    while right < n:
        subarray_sum = sum(nums[left:right+1])
        if subarray_sum < target:
            right += 1
        else:
            min_len = min(min_len, right - left + 1)
            left += 1

    return min_len

总结

LeetCode 209 题是一道经典的动态规划题目,要求我们找到一个连续子数组,使得其元素之和大于或等于一个给定的目标值,同时还应满足长度最小的条件。通过结合动态规划和滑动窗口这两种算法技巧,我们可以高效地求解此题。希望本文能够帮助你更好地理解和掌握这道题目的解决方法。