Minimum Size Subarray Sum 和满足要求的最小窗口

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).

这个问题跟前面的最小窗口子串问题是类似。这里会介绍时间复杂度分别为 O ( n ) 和 O (n log n )的2种解法。

有2个指针,start, end 表示子串的开始和结束。

1. 从start index = 0 开始,先找到和满足要求的子串。

2. start++看看有没有更小的子串。

最小对求得的更小子串求min,得到最终的最小子串了。

这个算法的时间复杂度为 O ( n )。

运行时间:

Minimum Size Subarray Sum 和满足要求的最小窗口_第1张图片

代码:

    public int minSubArrayLen(int s, int[] nums) {
        int start = 0, end = 0, n = nums.length, curSum = 0, minLen = Integer.MAX_VALUE;
        while (end < n) {
            //find the valid window
            while (end < n && curSum < s) {
                curSum += nums[end++];
            }
            if (curSum < s) {
                break;
            }
            //try to find a smaller window
            while (start < end && curSum >= s) {
                curSum -= nums[start++];
            }
            if (end - start + 1 < minLen) {
                minLen = end - start + 1;
            }
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
    }
O (n log n)的解法参考于:

https://discuss.leetcode.com/topic/13749/two-ac-solutions-in-java-with-time-complexity-of-n-and-nlogn-with-explanation

以:nums : [ 2 3 1 2 4 3], 求 s = 7为例。

我新创建一个累计和的数组 sums 为[ 0 2 5 6 8 12 15]。sums[ i ] 表示nums 中 index < i 的所有值的和。

对于nums, index = i  的时候,我想要找到跟 i 间隔值为s的下标。即在新数组中 >= sums[ i ] + s 值的下标。因为新数组是有序的,所以可以通过二分查找进行搜索。每次搜索的时间复杂度度为logN, 所有总的时间复杂度为O ( N log N )。

代码:

    private int binarySearch(int lo, int hi, int key, int[] sums) {
        while (lo <= hi) {
            int mid = (lo + hi) / 2;
            if (sums[mid] >= key) {
                hi = mid - 1;
            } else {
                lo = mid + 1;
            }
        }
        return lo;
    }

    public int solveNlogN(int s, int[] nums) {
        int[] sums = new int[nums.length + 1];
        for (int i = 1; i <= nums.length; i++) {
            sums[i] = sums[i - 1] + nums[i - 1];
        }
        int minLen = Integer.MAX_VALUE;
        for (int i = 0; i < sums.length; i++) {
            int end = binarySearch(i + 1, sums.length - 1, sums[i] + s, sums);
            if (end == sums.length) {
                break;
            }
            if (end - i < minLen) {
                minLen = end - i;
            }
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
    }

你可能感兴趣的:(数据结构,string,算法,leetcode,substring,leetcode)