#! /usr/bin/env python
# -*- coding: utf-8 -*-
# 给定一个含有
# n
# 个正整数的数组和一个正整数
# s ,找出该数组中满足其和 ≥ s
# 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回
# 0。
#
#
#
# 示例:
#
# 输入:s = 7, nums = [2, 3, 1, 2, 4, 3]
# 输出:2
# 解释:子数组[4, 3]
# 是该条件下的长度最小的连续子数组。
class Solution(object):
def minSubArrayLen(self, s, nums):
"""
我一直以为,如果是套公式,搞出这个解答,其价值只值五毛钱
:type s: int
:type nums: List[int]
:rtype: int
"""
# 长度最小的连续子数组长度,那么这个长度肯定是一个值,而不是两个值(废话)
# 正常逻辑:O(n**3),
# 1,找出所有的可能连续子数组(n+n-1+n-2+...+1个子数组)
# 2,对每一个子数组的数加一下得到各自的`和`(每个需要O(n)复杂度)
# 3,排除`和`大于等于给定n的子数组,从中矮子里面挑将军
# 非正常思维:
# 1,结果数组是有规律的:必须连续子数组
# 2,上面第二步骤有很多重复的加操作
# 3,最后只需要一个数,而不是多个(是不是还觉得是废话)
# 扫描数组,符合条件的子数组,
# 肯定是两者之一:当前扫描所在index之前的和其他的(卧槽还是废话)
# 那么我只需要记下算上当前元素最短子串,以及当前元素之前的最短子串(哎呦上面这句好像不是废话了)
# 而不需要记下别的,因为最终是获得一个值,这个值肯定在这俩值之间(哦,第一句也不是废话),大可以猴子下山,捡个西瓜丢个芝麻
# 牛逼的人这么想:
# 卧槽卧槽,这个我知道,就是那个动态规划就行了,别管贝尔曼是怎么提出动态规划的,找到 f(n) = min(f(n-1), g(n)),len(f(n))就是结果,just coding
total = reduce(lambda x, y: x+y, nums)
if total < s:
return 0
min_len, sum_ret = len(nums), total # f(i-1)
start_i, end_i, sum_i = 0, 0, 0 # g(i)
for i in range(len(nums)):
sum_i += nums[i]
end_i = i
while sum_i >= s:
min_len = min(min_len, end_i - start_i + 1)
sum_ret = min(sum_ret, sum_i)
sum_i -= nums[start_i]
start_i += 1
return min_len
if __name__ == '__main__':
s = Solution()
print(s.minSubArrayLen(7, [1,2,1,4]))
动态规划系列1
最新推荐文章于 2024-05-05 16:41:18 发布