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