先附上题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
解题方法:滑动窗口法
解题思路:
1.判断数组是否为空(在做数组类题目是一定要记住这一点,我每次都忘记,在这里自罚三杯!)
2.明确三个问题:
- 窗口的起始位置和终止位置在哪?
- 窗口里包含什么值?
- 窗口什么时候动?
3.逐一解决上述三个问题
3.1 窗口的起始位置和终止位置在哪?
显然,初始状态下,起始位置与终止位置都在列表的第一个元素处。
因为我们总是要从第一个元素开始遍历的,不能有漏网之鱼哦。
3.2 窗口里包含什么值?
首先应该满足一个条件:窗口中所有值的和是大于等于目标值的!
- 这里我要说一下自己的想法:其实可以把窗口看作一个子序列,若子序列的和大于目标值则可以证明这个子序列中是有我们想找的数字的,不管最后是不是在这个子序列中找到的,最起码这个子序列中的值是有可能被选中的。
3.3 窗口什么时候动?
- 窗口动可以分为两个子问题:起始位置什么时候动和终止位置什么时候动
- 起始位置什么时候动:当窗口中所有值的和是大于等于目标值时。有人可能会有疑问为啥等于时候还动呐?等于时候当然要动啊,因为你要找的是最小的序列呀(找最小值就体现在代码里的min函数,这里还要在啰嗦一下:初始的要给ans一个大于数组长度的值,这样的话才能在第一次找到候选子序列的时候成功将子序列的长度赋值给ans,之后每一次的取最小值的操作其实就是在与之前过程中的最小值作比较,看最小,谁就是最后的赢家)!现在已经等于目标值了,刚好就是你要找的序列之一啊(如果有多个满足条件的序列存在)再添加一个值进窗口那铁定大于目标值了啊,你肯定要缩小窗口啊!
- 终止位置什么时候动:终止位置移动是为了不断地往窗口里添加新的值,不断地形成新的子序列。大家想想为啥动啊,那肯定是数太小了啊,需要再大点啊,怎么再大点呢,不就是继续加新元素的值嘛。
思路捋清楚了就上代码了!
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
n = len(nums)
start, end = 0, 0
ans = n + 1
sum = 0
while end < n:
sum += nums[end]
while sum >= target:
ans = min(ans, end - start + 1)
sum -= nums[start]
start += 1
end += 1
return 0 if ans == n + 1 else ans
这里说明一下,我也是站在了巨人的肩膀上,参考了代码随想录的解题思路!推荐推荐!!!
还想鼓励大家一下,做不出来的时候别气馁,学会别人的解题思路,慢慢地积累,形成算法思想,毕竟每个领域的领头人也就那么几个,大佬也是从不会到会的,本人也是菜鸟一直,共勉!