leetcode862_和至少爲K的最短子數組_單調雙端隊列&前綴和

1. 這題感覺真的很難, 首先求和的方法轉換爲前綴和的形式,避免重複計算.想求[i,j]區間則爲sum[i+1]-sum[j].

2. 運用單調雙端隊列解決應該選擇哪個區間的問題.因爲如果存在負數,則需要把包含負數區間的求和去掉,因爲負數後面的數肯定也符合條件>=K,而且長度也比較小.

class Solution {
public:
    int shortestSubarray(vector<int>& A, int K) {
        if(A.size()==0) return -1;
        //定義A.size()+1長度的數組,包含sum[0].
        //解決sum[1]=sum[0]+A[0]情況.
        //前綴和sum[i]代表[0,i-1]區間的求和.
        vector<int> sum(A.size()+1, 0);
        deque<int> dq;
        int res = INT_MAX;
        for(int i=1;i<=A.size();i++) {
            sum[i] = sum[i-1]+A[i-1];
        }
        //單調雙端隊列保證單增,如果存在小於等於的情況,
        //說明裏面一定包含負數或0,去掉dq最後一個值.
        //從dq最前尋找符合>=K條件的長度,並計算最短長度.
        for(int i=0;i<=A.size();i++) {
            if(i!=0) {
                while(dq.size()>0 && sum[dq.back()]>=sum[i]) dq.pop_back();
                while(dq.size()>0 && sum[i]-sum[dq.front()]>=K) {
                    res = min(res, i-dq.front());
                    dq.pop_front();
                }
            }
            dq.push_back(i);
        }
        //有可能不存在,則返回-1.
        return res==INT_MAX ? -1:res;
    }
};

發佈了95 篇原創文章 · 獲贊 26 · 訪問量 2115
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章