• 0209-leetcode算法实现之长度最小子数组-minimum-size-subarray-sum-python&golang实现


    给定一个含有 n 个正整数的数组和一个正整数 target 。

    找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

    示例 1:

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

    输入:target = 4, nums = [1,4,4]
    输出:1
    示例 3:

    输入:target = 11, nums = [1,1,1,1,1,1,1,1]
    输出:0

    提示:

    1 <= target <= 109
    1 <= nums.length <= 105
    1 <= nums[i] <= 105

    进阶:

    如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum

    python

    # 长度最小的子数组
    # 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
    class Solution:
        def minSubArrayLen(self, nums: [int], target: int) -> int:
            """
            滑动窗口,时间O(n), 空间O(1)
            思路:
            1.初始化求和sum,返回结果res,左边界index=0
            2.移动右边界,sum累加计和
            3.当sum < target,不断累加计和,重复步骤2
            4.当sum >= target,考虑移动左边界,减小sum值,res取上步res及序列长度i-index+1的较小值
            5.重复步骤4,直到sum < target,重复步骤3
            6.遍历结束后,取到的res即为满足target计和的子序列长度最小的数组长度
            :param nums:
            :param target:
            :return:
            """
            res = float('inf')
            sum = 0
            index = 0
            for i in range(len(nums)): # 窗口右边界,不断右移
                sum += nums[i] # 累加计和
                while sum >= target: # 滑动窗口精髓,只有当累加和大于等于target,取小值长度更新res,sum减去左边界元素,左边界继续右移, 即index++
                    res = min(res, i-index+1) # 取长度小值,因为 sum >= target
                    sum -= nums[index] # 窗口左边界右移,sum减小, 左边界index右移
                    index += 1
            return 0 if res == float('inf') else res
    
    
        def minSubArrayLen1(self, nums: [int], target: int) -> int:
            """
            暴力法, 时间O(n^2), 空间O(1)
            思路:
            1.初始化变量,即序列长度
            2.从数组的第一个元素i开始,从该元素取j往后遍历,依次累加计和,每次初始化sum为0(暴力法)
            3.如果sum大于等于target,此时记录其连续序列长度即j-i+1
            4.res即序列长度和sublen比较,取小值,跳出该次遍历
            5.重复2、3、4,直至遍历完所有元素,此时的res就是序列最小的符合条件的长度
            :param nums:
            :param target:
            :return:
            """
            INT_MAX = 2**31 - 1
            res = INT_MAX # 初始化res, 最终结果变量
            for i in range(len(nums)): # 子序列起点i
                sum = 0 # 每次更新其实位置时,置零---暴力法,每次遍历元素,重新置零,表示本轮元素的结果
                for j in range(i, len(nums)): # 设置子序列的终止位置j
                    sum += nums[j] # 逐次累加
                    if sum >= target: # 子序列和超过target,更新res
                        sublen = j - i + 1 # 子序列长度
                        res = min(res, sublen) # 保持最小的res
                        break # 小者,条件最短的子序列
            return 0 if res == INT_MAX else res # res没有更新,则返回0
    
    
    
    
    
    if __name__ == "__main__":
        nums = [1,2,3,5,2,1,1,4,1]
        target = 9
        target1 = 13
        test = Solution()
        print(test.minSubArrayLen(nums,target))
        print(test.minSubArrayLen1(nums,target1))
    

    golang

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	nums := []int{1, 2, 3, 5, 2, 1, 1, 4, 1}
    	target := 9
    	fmt.Println(minSubArrayLen(target, nums))
    }
    
    // 滑动窗口-时间O(n)
    func minSubArrayLen(target int, nums []int) int {
    	const INT_MAX = int(^uint(0) >> 1)
    	var res int = INT_MAX
    	var sum int
    	var index int = 0
    	for i := 0; i < len(nums); i++ {
    		sum = sum + nums[i]
    		for sum >= target {
    			if res < i-index+1 {
    				res = res
    			} else {
    				res = i - index + 1
    			}
    			sum = sum - nums[index]
    			index++
    		}
    	}
    	if res == INT_MAX {
    		return 0
    	} else {
    		return res
    	}
    }
    
    // 暴力法-时间O(n^2)
    func minSubArrayLen1(target int, nums []int) int {
    	const INT_MAX = int(^uint(0) >> 1)
    	var res int = INT_MAX
    	var sum int
    	var sublen int
    	for i := 0; i < len(nums); i++ {
    		sum = 0
    		for j := i; j < len(nums); j++ {
    			sum = sum + nums[j]
    			if sum >= target {
    				sublen = j - i + 1
    				if res < sublen {
    					res = res
    				} else {
    					res = sublen
    				}
    				break
    			}
    		}
    	}
    	if res == INT_MAX {
    		return 0
    	} else {
    		return res
    	}
    }
    
  • 相关阅读:
    Java的JXL操作xls形式
    UILabel iOS添加文本控件
    并行随机梯度下降
    ArcGIS For Flex给定两个
    如何判断一个网址是由哪种语言写的
    ArrayList线程不安全?
    java总结,错误集
    centos安装Chromium
    读书笔记:《从一到无穷大》
    读书笔记:《数学之美》
  • 原文地址:https://www.cnblogs.com/davis12/p/15413342.html
Copyright © 2020-2023  润新知