1. 程式人生 > >LeetCode:862. 和最短為k的最短子陣列[Java實現]

LeetCode:862. 和最短為k的最短子陣列[Java實現]

題目

返回 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 <= A.length <= 50000
-10 ^ 5 <= A[i] <= 10 ^ 5
1 <= K <= 10 ^ 9

思路:這一題用普通的兩個迴圈肯定是要超時的。可以選擇用map將下表i之前的數字的和s

儲存起來,和s作為key,i作為value,當計算到s時,從map的key中選出滿足s-key>=K的Entry, 用當前的下標i 減去Entry的value,也就是滿足和為key的下標(value),len = i - value, 將len和minLength比較,minLength = min(len, minLength) ,更新minLength。

程式碼如下

class Solution {
    public int shortestSubarray(int[] A, int K) {
        int MAX = 50001;
        TreeMap<
Long, Integer>
map = new TreeMap<Long, Integer>(); long sum = 0; int minL = MAX; long minSum = 100000000; for (int i = 0; i < A.length; i++) { sum += A[i]; if(sum >= K && minL > i + 1) minL = i + 1; long
sub = sum - K; while (!map.isEmpty()) { Map.Entry<Long, Integer> subEntry = map.floorEntry(sub); if (subEntry == null) break; long k = subEntry.getKey(); int j = subEntry.getValue(); if (i - j < minL) { minL = i - j; } map.remove(k); } if (sum < minSum) { minSum = sum; map.clear(); } map.put(sum, i); } if (minL == MAX) return -1; return minL; } }