zoukankan      html  css  js  c++  java
  • 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
    	}
    }
    
  • 相关阅读:
    ADB命令大全
    Backup your Android without root or custom recovery -- adb backup
    Content portal for Pocketables Tasker articles
    Is there a way to detect if call is in progress? Phone Event
    Tasker to proximity screen off
    Tasker to detect application running in background
    Tasker to create toggle widget for ES ftp service -- Send Intent
    Tasker to proximity screen on
    Tasker to answer incoming call by pressing power button
    Tasker to stop Poweramp control for the headset while there is an incoming SMS
  • 原文地址:https://www.cnblogs.com/davis12/p/15413342.html
Copyright © 2011-2022 走看看