Question:
Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn‘t one, return 0 instead.
For example, given the array [2,3,1,2,4,3]
and s = 7
,
the subarray [4,3]
has the minimal length under the problem constraint.
More practice:
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
Analysis:
给出n个正整数的数组和一个正整数s,找出这个数组中组数组之和sum>=s的最小程度。如果不存在,则返回0.
你可以有O(n)和O(nlogn)两种解决方案。
Answer:
思路1. 刚开始考虑这个题目时,想到的是首先遍历一遍数组,找到数组中的最大值,然后围绕最大值的左边与右边累加,直至sum>=s。但是一种情况是如果数组中存在多个相同的最大值怎么办。。这样的话用这个方法就不行了。
代码:
public class Solution { public int minSubArrayLen(int s, int[] nums) { if(nums == null || nums.length == 0) return 0; int max = Integer.MIN_VALUE; int col = -1; for(int i=0; i<nums.length; i++) { if(max < nums[i]) { max = nums[i]; col = i; } } int len = 1; int sum = max; if(col > 0 && col < nums.length - 1) { int i = col - 1, j = col + 1; while(sum < s && i >= 0 && j <= nums.length - 1) { if(nums[i] <= nums[j]) { sum += nums[j]; len++; j++; } else { sum += nums[i]; len++; i--; } } } else if(col == 0) { //nums[0] is the maximum int j = col + 1; while(sum < s && j < nums.length) { sum += nums[j]; len++; j++; } } else { //nums[n-1] is the maximum int i = col - 1; while(sum < s && i >= 0) { sum += nums[i]; len++; i--; } } if(sum < s) return 0; return len; } }思路2. 参考网上O(n)的解决方案,给出两个指针,left and right, 首先right从左到右加,至第一次sum>=s时,然后再一次减去left的值,直至sum<s;然后下一次再right向右移动,然后再减去left依次移动的值。当然,中间要保存每次子数组之和大于s的长度,最后返回最小的数组长度即可。(注意两种特殊情况,整个数组加起来正好等于s;整个数组加起来也小于s)
public class Solution { public int minSubArrayLen(int s, int[] nums) { if(nums == null || nums.length == 0) return 0; int left = 0, right = 0, res = nums.length + 1; int sum = 0; while(right < nums.length) { while(sum < s && right < nums.length) { sum += nums[right++]; } while(sum >= s) { res = Math.min(res, right - left); sum -= nums[left++]; } } return res == nums.length + 1 ? 0 : res; } }
思路3. O(nlogn)的解决方案。
还没看懂。。囧。。
时间: 2024-10-22 08:54:34