leetcode-209-最小连续子数组

leetcode-209
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。

示例:

输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。

进阶:

如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。

思路:

  • 暴力求解法
    找到每个子序列,判断子序列和,如果小于那么就尝试增加数字,如果大于就尝试减少数字
    但是仍然是找到了每一个子序列,时间复杂度 O(N^3), 空间复杂度O(1)
class Solution(object):
    def minSubArrayLen(self, s, nums):
        """
        :type s: int
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)+1
        end, start = 0, 0
        while(end < len(nums) and end >= start):           
            if sum(nums[start:end + 1]) < s:
                end += 1
            else :
                length = min(length, end - start + 1)        
                start += 1
        return length if length != len(nums)+1  else 0
  • 优化暴力解
    在刚才的做法中是对于找到每个子序列,在这里需要O( N^2 )的时间复杂度,然后在子序列内求和需要O(N)的时间复杂度,所以整体需要O(N^3)的时间复杂度
    在这个算法中,在计算子序列和的时候可以将时间复杂度降为O(1)
    具体做法是,记录一个到当前值的所有序列和,及S[j] 表示从0 -J的和
    在实际赋值计算中s[j] = s[j-1]+nums[j]
    在计算子序列和时 sum[i,j] = s[j]-s[i]+nums[i]
    这样在计算子序列和时时间复杂度为O(1),所有整体时间复杂度为O(N^2)
class Solution(object):
    def minSubArrayLen(self, s, nums):
        """
        :type s: int
        :type nums: List[int]
        :rtype: int
        """
        if nums == []:return 0
        length = len(nums) +1 
        subsum = [0]*len(nums)
        subsum[0] = nums[0]
        for i in range(1,len(subsum)):
            subsum[i] = (subsum[i-1]+nums[i])
        end, start = 0, 0
        while(end < len(nums) and end >= start):           
            if subsum[end]-subsum[start]+nums[start] < s:
                end += 1
            else :
                length = min(length, end - start + 1)        
                start += 1
        return length if length != len(nums)+1  else 0
  • 双指针法
    还是找到子序列,设置该子序列的的左右指针,移动右指针循环,当满足了要求的时候是当前左指针的最短长度
    然后依次把左面的符合要求的也就是让那些使得和大于S的位置去掉,重新设置左指针
    这样只需要循环一遍右指针,当找到符合要求的时候去掉多余的左指针,或者称之为重置左指针
class Solution(object):
    def minSubArrayLen(self, s, nums):
        """
        :type s: int
        :type nums: List[int]
        :rtype: int
        if nums == []:return 0
        length = len(nums) +1 
        sum = 0
        left = 0
        for right in range(len(nums)):
            sum +=nums[right]
            while sum>=s:
                length = min(length,right-left+1)
                sum -=nums[left]
                left+=1

        return length if length != len(nums)+1  else 0

版权声明:本文为qq_22235017原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。