LeetCode -- Minimum Size Subarray Sum

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.

click to show more practice.

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)的解决方案。

 还没看懂。。囧。。

 

posted @ 2016-03-31 21:51  江湖小妞  阅读(258)  评论(0编辑  收藏  举报