862. 和至少为 K 的最短子数组

返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。

如果没有和至少为 K 的非空子数组,返回 -1 。

示例 1:

输入:A = [1], K = 1
输出:1

示例 2:

输入:A = [1,2], K = 4
输出:-1

示例 3:

输入:A = [2,-1,2], K = 3
输出:3

提示:

  1. 1 <= A.length <= 50000
  2. -10 ^ 5 <= A[i] <= 10 ^ 5
  3. 1 <= K <= 10 ^ 9

Review : 

这道题真的是写了三遍....

为啥写了三遍... 第一次读错题了...我居然写成了最长的子数组..

然后我在最长子数组代码基础上改成了最短子数组...

由于逻辑不同超时...然后整理了下逻辑

得到了最优O(n) 最差O(n2)的答案

具体流程是遍历数组,累积前n项和,如果sum<=0,则起始指针前移;

当sum大于K时,反向贪心,起始指针能前移多少就前移多少,得到符合的值更新result


Code : 

买一赠二: 赠超时版和最长子数组版

正版:

class Solution {
    public int shortestSubarray(final int[] A, int K) {
        int len = A.length;
        int sum = 0, begin = 0, res = -1;
        for (int i = 0; i < len; i++) {
            if (A[i] >= K) return 1;
            sum += A[i];
            if (sum < 1) {
                sum = 0;
                begin = i + 1;
                continue;
            }
            for (int j = i - 1; A[j + 1] < 0; j--) {
                A[j] = A[j + 1] + A[j];
                A[j + 1] = 0;
            }
            if (sum >= K) {
                while (sum - A[begin] >= K || A[begin] <= 0) 
                    sum -= A[begin++];
                int length = i - begin + 1;
                if (res < 0 || res > length) 
                    res = length;
            }
        }
        return res;
    }
}

超时版:

    public int shortestSubarray(int[] A, int K) {
        int len = A.length;
        int[] sum = new int[len + 1];
        sum[1] = A[0];
        for (int i = 1; i < len; i++)
            sum[i + 1] = sum[i] + A[i];
        int minLen = Integer.MAX_VALUE;
        for (int i = 0; i < len; i++) {
            if (i != 0 && A[i] >= K) 
                return 1;
            for (int j = i + 1; j < len + 1; j++) {
                if (sum[j] - sum[i] >= K) {
                    minLen = Math.min(minLen, j - i);
                    break;
                }
            }
        }
        return minLen == Integer.MAX_VALUE ? -1 : minLen;
    }

看错题版(最长子数列):

    //妈的做成最长的了
    public int longestSubarray(int[] A, int K) {
        int len = A.length;
        int[] sum = new int[len + 1];
        sum[1] = A[0];
        for (int i = 1; i < len; i++) 
            sum[i + 1] = sum[i] + A[i];
        int maxLen = -1;
        for (int i = 0; i < len; i++) {
            if (len - i < maxLen) 
                return maxLen;
            for (int j = len - 1; j > i + maxLen - 1; j--) 
                if (sum[j] - sum[i] >= K) 
                    maxLen = j - i + 1;
        }
        return maxLen;
    }

猜你喜欢

转载自blog.csdn.net/start_lie/article/details/88886344