代码随想录算法训练营第二天 (2)|209.长度最小的子数组

51 阅读2分钟

题目描述

给定一个含有 n 个正整数的数组和一个正整数 target 

找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度**。**如果不存在符合条件的子数组,返回 0 。

代码示例

from typing import List

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        min_length = float('inf')  # 将结果初始化为正无穷大
        left_ptr = 0  # 慢指针初始化在数组的开头
        current_sum = 0  # 用于跟踪当前子数组的和的变量

        for right_ptr in range(len(nums)):
            current_sum += nums[right_ptr]  # 将当前元素添加到子数组的总和中

            while current_sum >= target:
                current_length = right_ptr - left_ptr + 1  # 计算当前子数组的长度
                min_length = min(min_length, current_length)  # 如果当前子数组较短,则更新结果
                current_sum -= nums[left_ptr]  # 从子数组中移除慢指针指向的元素
                left_ptr += 1  # 将慢指针向右移动

        return 0 if min_length == float('inf') else min_length  # 如果结果仍为正无穷大,则返回0

# 示例用法
if __name__ == "__main__":
    solution = Solution()

    # 示例 1
    target1 = 7
    nums1 = [2, 3, 1, 2, 4, 3]
    result1 = solution.minSubArrayLen(target1, nums1)
    print(f"示例 1:至少具有和为 {target1} 的子数组的最小长度:{result1}")

    # 示例 2
    target2 = 11
    nums2 = [1, 1, 1, 1, 1, 1, 1, 1]
    result2 = solution.minSubArrayLen(target2, nums2)
    print(f"示例 2:至少具有和为 {target2} 的子数组的最小长度:{result2}")

学习记录

  • 第一想法: 使用双指针遍历叠加大于等于 target 的长度,对比 result 的值,如果长度小于 result 则替换。result 初始值为数组长度。
  • 代码随想: 只需一个循环完成查找,符合条件后替换 result。当符合判断条件后,数组左侧缩进是循环缩减,一直到和小于 target
  • 实现困难: 计算子数组长度时,使用 right_ptr - left_ptr 造成长度计算偏差,应该为 right_ptr - left_ptr + 1
  • 今日学习时长: 耗时 1 小时完成本题学习。

学习心得

  • 在解决问题时,保持灵活性和开放心态很重要。一开始的想法并不一定是最优的解决方案,有时候需要不断调整和优化。
  • 学会从代码中汲取经验教训,例如正确地计算子数组长度。这样的细节决定了程序的正确性。
  • 通过这道题目,我更加熟悉了移动窗口的应用,学到了一些在处理子数组长度时的注意事项。这不仅提高了我的算法水平,还对编写高效、健壮的代码有所帮助。