动态规划系列1

#! /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]))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值