【滑動(dòng)窗口】209. 長(zhǎng)度最小的子數(shù)組

給定一個(gè)含有 n 個(gè)正整數(shù)的數(shù)組和一個(gè)正整數(shù) target 闭专。
找出該數(shù)組中滿足其和 ≥ target 的長(zhǎng)度最小的 連續(xù)子數(shù)組 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其長(zhǎng)度慎宾。如果不存在符合條件的子數(shù)組舌菜,返回 0 慢味。
● 進(jìn)階:如果你已經(jīng)實(shí)現(xiàn) O(n) 時(shí)間復(fù)雜度的解法, 請(qǐng)嘗試設(shè)計(jì)一個(gè) O(n log(n)) 時(shí)間復(fù)雜度的解法。

解題思路:
● 方式一:滑動(dòng)窗口盔几。 時(shí)間復(fù)雜度:O(n)
設(shè)立指針i晴弃,j,初始化下標(biāo)均為0逊拍。j 不斷后移上鞠,并且計(jì)算當(dāng)前窗口的和sum,直到sum ≥ target芯丧。此時(shí)后移i指針芍阎,并更新sum,直到無(wú)法再移動(dòng) i 缨恒。重復(fù)上述步驟谴咸,直到 j 完成遍歷轮听。在此過(guò)程中記錄滑動(dòng)窗口的最小值。
● 方式二:數(shù)組前綴和 + 二分查找 時(shí)間復(fù)雜度:O(nlogn)
由于該數(shù)組是一個(gè)正整數(shù)數(shù)組岭佳,計(jì)算出來(lái)的前綴和數(shù)組sums一定是一個(gè)遞增數(shù)組血巍,滿足二分條件。
??定義sums[i] = nums[1] + nums[2] + …… + nums[i];
??則sums[n] - sums[m] = nums[m+1] + nums[m+2] + …… + nums[n].(此時(shí)不包含nums[m])
問(wèn)題需求:sums[n] - sums[m] >= target珊随,等價(jià)于sums[m] + target <= sums[n]述寡。
此時(shí)問(wèn)題可以轉(zhuǎn)換為,當(dāng)固定開(kāi)始下標(biāo)為m+1時(shí)叶洞,target(新) = sums[m] + target(舊)鲫凶,在遞增數(shù)組sums中找到第一個(gè)≥target(新)的元素下標(biāo)。
\color{red}{注意:下標(biāo)為m的元素衩辟,會(huì)在減法的時(shí)候被移除螟炫,所以并不包含在內(nèi)。}
\color{red}{因此艺晴,sums數(shù)組的長(zhǎng)度為nums.length + 1不恭,保證下標(biāo)為0的元素也可以作為開(kāi)始元素。}
舉例:
sums[0] + target(舊) → 找到從下標(biāo)1開(kāi)始的滿足題意的最小長(zhǎng)度
sums[1] + target(舊) → 找到從下標(biāo)2開(kāi)始的滿足題意的最小長(zhǎng)度
……
sums[n-2] + target(舊) → 找到從下標(biāo)n-1開(kāi)始的滿足題意的最小長(zhǎng)度(n為數(shù)組長(zhǎng)度)
?【sums[n-1]也要被計(jì)算财饥,因?yàn)殡m然sums[n-1]不作為開(kāi)始下標(biāo),但是可以作為結(jié)束下標(biāo)折晦,從另一個(gè)角度說(shuō)钥星,需要把全部元素的和計(jì)算一遍】

? 對(duì)上述結(jié)果觀察,可以發(fā)現(xiàn)nums[0]沒(méi)有被包括進(jìn)來(lái)满着,所以我們要重新修改sums的定義谦炒。
??定義sums[i] = nums[1] + nums[2] + …… + nums[i-1];
??則sums[n] - sums[m] = nums[m] + nums[m+1] + …… + nums[n].(此時(shí)包含nums[m])

問(wèn)題需求【不變】:sums[n] - sums[m] >= target,等價(jià)于sums[m] + target <= sums[n]风喇。
此時(shí)問(wèn)題可以轉(zhuǎn)換為宁改,當(dāng)固定開(kāi)始下標(biāo)為【m】時(shí),target(新) = sums[m] + target(舊)魂莫,在遞增數(shù)組sums中找到第一個(gè)≥target(新)的元素下標(biāo)还蹲。
舉例:
sums[0] + target(舊) → 找到從下標(biāo)0開(kāi)始的滿足題意的最小長(zhǎng)度
sums[1] + target(舊) → 找到從下標(biāo)1開(kāi)始的滿足題意的最小長(zhǎng)度
……
sums[n-1] + target(舊) → 找到從下標(biāo)n-1開(kāi)始的滿足題意的最小長(zhǎng)度(n為數(shù)組長(zhǎng)度)
?【sums[n]也要被計(jì)算,因?yàn)殡m然sums[n-1]不作為開(kāi)始下標(biāo)耙考,但是可以作為結(jié)束下標(biāo)谜喊,從另一個(gè)角度說(shuō),需要把全部元素的和計(jì)算一遍】倦始!
因此斗遏,通過(guò)遍歷每一個(gè)sums元素【為了固定開(kāi)始下標(biāo)】,調(diào)用二分查找鞋邑,并在此過(guò)程中記錄最小的長(zhǎng)度诵次,即可完成所求账蓉。

Java

● 方式一
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int i = 0;
        int j = 0;
        int sum = 0;
        int result = nums.length;
        while(j < nums.length){
            sum += nums[j];
            if(sum >= target){
                
                // 嘗試移動(dòng)i指針
                int tmp = (sum-nums[i]);
                while(tmp >= target){
                    sum = tmp;
                    i++;
                    tmp = (sum-nums[i]);
                }

                tmp = j - i + 1;
                if(result > tmp) result = tmp;

            }
            j++;
        }
        
        if(sum < target) return 0;
        else return result;
    }
}

● 方式二
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum[] = new int[nums.length + 1];
        sum[0] = 0; // 包括nums[0]
        for(int i=1; i<sum.length; i++){
            sum[i] = sum[i - 1] + nums[i - 1];
        }
        int result = Integer.MAX_VALUE;
        // 開(kāi)始固定開(kāi)始下標(biāo)
        for(int i=0; i<nums.length; i++){
            int newTarget = target + sum[i];
            // 二分查找sums遞增數(shù)組:找到第一個(gè)比newTarget大的元素下標(biāo)
            int l =  i;
            int r = sum.length - 1;
            int mid = l + (r - l) / 2;
            while(l <= r){
                mid = l + (r - l) / 2;
                if(sum[mid] < newTarget){
                    l = mid + 1;
                }else{ // sum[mid] >= newTarget
                    r = mid - 1; // 保證下標(biāo)為l的是正確的
                }
            }
            if(l >= sum.length) continue; // 說(shuō)明找不到
            int curLen = l - i; // sum[t] 不包括 num[t]
            if(result > curLen) result = curLen;
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市逾一,隨后出現(xiàn)的幾起案子铸本,更是在濱河造成了極大的恐慌,老刑警劉巖嬉荆,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件归敬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鄙早,警方通過(guò)查閱死者的電腦和手機(jī)汪茧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)限番,“玉大人舱污,你說(shuō)我怎么就攤上這事∶峙埃” “怎么了扩灯?”我有些...
    開(kāi)封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)霜瘪。 經(jīng)常有香客問(wèn)我珠插,道長(zhǎng),這世上最難降的妖魔是什么颖对? 我笑而不...
    開(kāi)封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任捻撑,我火速辦了婚禮,結(jié)果婚禮上缤底,老公的妹妹穿的比我還像新娘顾患。我一直安慰自己,他們只是感情好个唧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布江解。 她就那樣靜靜地躺著,像睡著了一般徙歼。 火紅的嫁衣襯著肌膚如雪犁河。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天鲁沥,我揣著相機(jī)與錄音呼股,去河邊找鬼。 笑死画恰,一個(gè)胖子當(dāng)著我的面吹牛彭谁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播允扇,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼缠局,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼则奥!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起狭园,我...
    開(kāi)封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤读处,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后唱矛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罚舱,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年绎谦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了管闷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窃肠,死狀恐怖包个,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冤留,我是刑警寧澤碧囊,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站纤怒,受9級(jí)特大地震影響糯而,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泊窘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一歧蒋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧州既,春花似錦、人聲如沸萝映。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)序臂。三九已至蚌卤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奥秆,已是汗流浹背逊彭。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留构订,地道東北人侮叮。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像悼瘾,于是被迫代替她去往敵國(guó)和親囊榜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子审胸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345