既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
解题思路
枚举数组 nums 中的每个下标作为子数组的开始下标,对于每个开始下标 i,需要找到大于或等于 i 的最小下标 j,使得从 nums[i] 到 nums[j] 的元素和大于或等于 s,并更新子数组的最小长度(此时子数组的长度是 j−i+1)。
代码实现
func minSubArrayLen1(target int, nums []int) int {
minLen := math.MaxInt
for i := 0; i < len(nums); i++ {
sum := 0
for j := i; j < len(nums); j++ {
sum += nums[j]
if sum >= target {
minLen = min(minLen, j-i+1)
break
}
}
}
if minLen == math.MaxInt {
return 0
}
return minLen
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
复杂度分析
- 时间复杂度:O(n^2 ),其中 n 是数组的长度。需要遍历每个下标作为子数组的开始下标,对于每个开始下标,需要遍历其后面的下标得到长度最小的子数组。
- 空间复杂度:O(1)。
方法二:滑动窗口 + 双指针
解题思路
定义两个指针 left 和 right 分别表示子数组(滑动窗口)的开始位置和结束位置,维护变量 sum 存储子数组中的元素和(即从 nums[left] 到 nums[right] 的元素和)。
初始状态下,left 和 right 都指向下标 0,sum 的值为 0。每一轮迭代,将 nums[right] 加到 sum,如果 sum≥target,则更新子数组的最小长度(此时子数组的长度是 right−left+1),然后将 nums[left] 从 sum 中减去并将 left 右移,直到 sum<target,在此过程中同样更新子数组的最小长度。在每一轮迭代的最后,将 right 右移。
代码实现
func minSubArrayLen(target int, nums []int) int {
left, right := 0, 0
minLen := math.MaxInt
sum := 0
for right < len(nums) {
sum += nums[right]
for sum >= target {
minLen = min(minLen, right-left+1)
sum -= nums[left]
left++
}
right++
}
if minLen == math.MaxInt {
return 0
}
return minLen
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
复杂度分析
- 时间复杂度:O(n),其中 n 是数组的长度。指针 left 和 right 最多各移动 n 次。
- 空间复杂度:O(1)。
方法三:前缀和 + 二分查找
解题思路
方法一采用暴力枚举,时间复杂度是 O(n^2 ),因为在确定每个子数组的开始下标后,找到长度最小的子数组需要 O(n) 的时间。如果使用二分查找,则可以将时间优化到 O(logn)。
每个下标开始的这个遍历过程计算了很多重复的区间,比如1,2,3,4 。以1为下标时计算了+2、+3、+4 ; 以2为下标时计算了+3、+4,像这种避免区间和重复计算的优化方法,我们想到了前缀和,可以O(1)时间迅速得到任意区间的和。
然后 ,我们可以很容易得改良问题为,求s[j] - s[i] >=target ,可是这种做法如果不加改变,就是在前缀和数组上进行类似方法一的暴力枚举,枚举每一个 i 后面的下标 j 。我们发现稍作变化,像这种线性的求值问题,联合二分查找可以做到 求 s[j] >=s[i]+target,将时间优化到 O(logn)。
代码实现
func minSubArrayLen(target int, nums []int) int {
ans := math.MaxInt32
sums := make([]int, 1)
for i := 1; i <= len(nums); i++ {
sums = append(sums, sums[i-1]+nums[i-1])
}
for i := 1; i <= len(nums); i++ {
num := target + sums[i-1]
bound := sort.SearchInts(sums, num)
if bound <= len(nums) {
ans = min(ans, bound-(i-1))
}
}
if ans == math.MaxInt32 {
return 0
}
return ans
}
func min(x, y int) int {
if x < y {
return x
}
![img](https://img-blog.csdnimg.cn/img_convert/131b027b18188d5c9d8d8c52fe5c83aa.png)
![img](https://img-blog.csdnimg.cn/img_convert/779e499285ec6338a51c0a6c0b2f86cd.png)
![img](https://img-blog.csdnimg.cn/img_convert/c6270c23b8171ba6a80941fd2fc43756.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**
涵盖了95%以上Go语言开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**