Leetcode: 209. Minimum Size Subarray Sum

本文探讨了在给定正整数数组中找到满足特定和条件的最短连续子数组的问题,提供了两种解决方案:暴力破解法(O(n^2))和滑动窗口法(O(n)),并详细解释了滑动窗口法如何在保持线性时间复杂度的同时,有效地找到满足条件的最小子数组。

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

Example: 

Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.

Follow up:

If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).

 

解法一(暴力破解):

最简单直接的方法就是使用暴力破解法。设两个指针用于标识遍历数组过程中的起止位索引,遍历数组中每一种起止位的可能。然后保存更新最短的连续长度即可。

// O(n^2)
	public static int minSubArrayLen(int s, int[] nums) {
		int minLen = Integer.MAX_VALUE ;
		
		for(int i=0; i < nums.length ; i++) {
			int tempSum = 0;
			for(int j=i; j<nums.length; j++) {
				tempSum += nums[j] ;
				if(tempSum >= s) {
					minLen = Math.min(minLen, j - i + 1) ;
				}
			}
		}
		
		return minLen == Integer.MAX_VALUE ? 0 : minLen;
	}

解法二(滑动窗口)

解法一时间复杂度显然是O(n^2),为了降低复杂度,可以使用滑动窗口。具体思想如下:假设找到了一组连续的子数组满足sum ≥ s,那么我们显然已经知道了这个子数组的起止位,也就是窗口的起止位。那么通过不断缩小窗口的大小,最终我们就可以得到最小的满足条件的窗口大小,也就是最短的子数组长度。

// O(n)
	public static int minSubArrayLen(int s, int[] nums) {
		int minLen = Integer.MAX_VALUE ;
		int left = 0 ;
		int sum = 0;
		for(int i=0; i < nums.length ; i++) {
			sum += nums[i] ;
			while(sum >= s) {
				minLen = Math.min(minLen, i - left + 1) ;
				sum -= nums[left++] ;
			}
		}
		
		return minLen == Integer.MAX_VALUE ? 0 : minLen;
	}

Note:

这个算法里面虽然是双层循环,但是复杂度依然是O(n)的。原因在于数组中的每一位,至多只会被访问两次。一次是被指针left,另一次是被指针i。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yexianyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值