【LeetCode】862. Shortest Subarray with Sum at Least K 解題報告(C++)
阿新 • • 發佈:2018-12-30
作者: 負雪明燭
id: fuxuemingzhu
個人部落格: http://fuxuemingzhu.cn/
目錄
題目地址:https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/
題目描述
Return the length of the shortest, non-empty, contiguous subarray of A
with sum at least K
If there is no non-empty subarray with sum at least K
, return -1
.
Example 1:
Input: A = [1], K = 1
Output: 1
Example 2:
Input: A = [1,2], K = 4
Output: -1
Example 3:
Input: A = [2,-1,2], K = 3
Output: 3
Note:
- 1 <= A.length <= 50000
- -10 ^ 5 <= A[i] <= 10 ^ 5
- 1 <= K <= 10 ^ 9
題目大意
求最短的子陣列長度,使得這個子陣列的和最少為K,如果不存在這樣的子陣列,返回-1.
解題方法
佇列
我嘗試了O(N^2)的解法,果然超時了。也對,題目給出的陣列長度是50000,基本上只有O(N)或者O(NlogN)的時間複雜度才行了。
這個題的做法要感謝lee215和演員的自我修養。下面的內容來自演員的自我修養。
分析:
- 顯然,我們會想到使用dp[i]記錄sum(A[:i]),那麼這道題就變成了,給定一個數組dp,找到一組i,j,使得dp[j]-dp[i]>=K,且j-i儘量小!
- 資料長度達到50000,顯然不能使用O(n^2)複雜度的方法,我們得想辦法讓i,j只走一遍
- 用一個簡單的示例來分析,設 A = [4,-1,2,3],,K = 5,那麼dp = [0,4,3,5,8],我們從dp陣列的第2個數開始分析,(假設來了個-1,那麼因為-1比0小,後面任意一個數val如若滿足val-0>K,那麼val+1也一定大於K,且-1所在的位置i顯然能獲得更優解,所以0這個位置就失去了意義),現在考慮示例,來了個4,我們發現4-0小於5,我們怎麼對4進行處理呢,因為考慮到之後或許會出現一個足夠大的數,比如9,那麼4相對於0是更優的,但也有可能只來一個8,那麼4就沒作用了,所以先暫且保留觀察。等到來了一個5以上的數,我們依次對保留的數(目前是0,4)進行判斷得最優解。
- 接下來來了個3,那麼根據上面提到的論點,4將會被捨棄,但3比0要大,故此時0,3保留。
- 然後來了個5,5-0>=5,故找到一組i,j,記錄下來,然後判斷 5-3>=5 ?如若確實大於,即再次找到一組i,j,若小於,則5保留(考慮到之後或許來了個10),依次類推
思路:
- 建立一個佇列記錄保留數字,初始為0
- 依次對dp中的數進行分析,如果dp[i] - dp[Q[0]] >= K,則記錄一次i,j
- 如果dp[i] < dp[Q[-1]],則捨棄Q[-1]
C++程式碼如下:
class Solution {
public:
int shortestSubarray(vector<int>& A, int K) {
const int N = A.size();
vector<int> preSum(N + 1, 0);
for (int i = 1; i < N + 1; i++) {
preSum[i] = preSum[i - 1] + A[i - 1];
}
int res = INT_MAX;
deque<int> q;
q.push_back(0);
for (int i = 1; i < N + 1; i++) {
int a = preSum[i];
while (!q.empty() && a - preSum[q.front()] >= K) {
res = min(res, i - q.front());
q.pop_front();
}
while (!q.empty() && a < preSum[q.back()]) {
q.pop_back();
}
q.push_back(i);
}
return res == INT_MAX ? -1 : res;
}
};
參考資料:
https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/discuss/143726/C%2B%2BJavaPython-O(N)-Using-Deque
https://buptwc.com/2018/07/02/Leetcode-862-Shortest-Subarray-with-Sum-at-Least-K/
日期
2018 年 12 月 20 日 —— 感冒害的我睡不著