zoukankan      html  css  js  c++  java
  • 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)的解决方案。

     还没看懂。。囧。。

  • 相关阅读:
    ssh的配置[待写]
    回文检测题解
    叠积木/银河系英雄传说[NOI2002]题解
    酒店之王解题报告
    摆花解题报告
    摆渡车(noip2018 pj t3)
    NOIP2018 普及 凉凉记
    子矩阵(NOIP2014T4)
    花店橱窗布置(洛谷:P1854)
    我想大声告诉你
  • 原文地址:https://www.cnblogs.com/little-YTMM/p/5342980.html
Copyright © 2011-2022 走看看