Leetcode: 209. Minimum Size Subarray Sum

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= 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。

你可能感兴趣的:(LeetCode,LeetCode)