长度最小的子数组(LeetCode209)

题目描述:

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

示例:

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

进阶:

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

思路:

首先,由题中的「连续」自然的想到「双指针」解法。

定义 start,end 两个指针,一个指向左边起始位置;一个指向右边结束位置,根据题目场景此题将左右指针初始化为数组下标0处。然后求和 sum 进行判断,如果 sum < s ,则 左指针 start 右移,如果 sum ≥ s 即符合要求,则记录长度 end - start + 1,并且 end 右移继续判断。

代码:

package main

import (
	"fmt"
	"math"
)

func main()  {
	s :=7
	nums := []int{2, 3, 4, 5, 6}
	fmt.Println(minSubArrayLen(s, nums))
}

// 双指针
// Go
func minSubArrayLen(s int, nums []int) int {
	length := len(nums) // 内置函数得出数组长度
	if length == 0 {
		return 0
	}
	ans := math.MaxInt32 // 定义结果为最大值
	start, end := 0, 0 // 左右边界
	sum := 0 // 临时变量存和
	// 遍历数组
	for end < length {
		// 求和
		sum += nums[end]
		// 当 sum 大或等于目标 s 时,则更新子数组的最小长度(此时子数组的长度是 end-start+1),并减去 nums[start] ,将 start 右移
		for sum >= s {
			ans = MinInt(ans, end-start+1) // 注:这里的 MinInt() 由于经常用到,故我将其放在工具包中。LeetCode运行时记得写在本文件中
			sum -= nums[start]
			start++
		}
		// sum 小于 s,将 end 右移
		end++
	}
	// 若果 ans 未改动,无符号条件返回 0
	if ans == math.MaxInt32 {
		return 0
	}
	return ans
}

// LeetCode 运行时可以写在
func MinInt(x, y int) int {
	if x < y {
		return x
	}
	return y
}

   地址:https://mp.weixin.qq.com/s/aQtSzoxt0NPn_H6RU5QU7A

posted @ 2020-07-08 10:32  small_lei_it  阅读(181)  评论(0编辑  收藏  举报