国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

假期算法提升(帶你徹底掌握滑動窗口)

這篇具有很好參考價值的文章主要介紹了假期算法提升(帶你徹底掌握滑動窗口)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

呀哈嘍,我是結(jié)衣。
今天我們要學(xué)習(xí)的是一種新的算法,也是一種雙指針。不過他擁有一個全新的名字”滑動窗口“。

1.長度最小的子數(shù)組(medium)

題目鏈接:長度最小的子數(shù)組
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

因為數(shù)組元素全為正整數(shù),使得數(shù)組具有了一種單調(diào)性。以示例1為例子,2+3+1+2會大于7,那么我們好有必要繼續(xù)向后遍歷嗎?沒有必要,所以我們就會想到去掉前面的一個數(shù)變成3+1+2這樣也就小于7啦,于是我們就繼續(xù)遍歷數(shù)組,3+1+2+4又會大于7了我就重復(fù)剛剛的操作,我們遍歷完數(shù)組。

解題方法

又上面的思路我們可以想到定義兩個指針left和right,right來遍歷數(shù)組,left在后面跟著,是雙指針不過有了新的名字“滑動窗口”
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享
在圖中我可以看到right和left共同維護著一段區(qū)間,而且right和left又可以移動,顧名思義就是滑動窗口
滑動窗口最重要的操作就是進窗口(移動right)判斷 出窗口(移動left) 更新結(jié)果
只要這幾步就可以做出題目來。
要注意的數(shù)更新結(jié)果的位置是不確定的,要根據(jù)具體的題目要求。

Code

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int sum = 0,n = nums.size();
        int len = INT_MAX;
        for(int left = 0,right = 0;right<n;right++)//right++為進窗口
        {
            sum+=nums[right];
            while(sum>=target)//判斷
            {
                len = min(len,right-left+1);//更新結(jié)果
                sum-=nums[left];
                left++;//出窗口
            }
        }
        return len==INT_MAX?0:len;
    }
};

2.無重復(fù)字符的最長子串(medium)

題目鏈接:無重復(fù)字符的最長子串
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

當(dāng)我們不知道怎么寫之前,我們可以運用暴力的方法先考慮問題。遍歷字符串時(示例1),當(dāng)我們遍歷到第二個a時我們此時就出現(xiàn)了重復(fù)的字符,我們可以繼續(xù)遍歷,但那就沒有必要了。我們可以重新遍歷從第二個字符開始,再向后舉行遍歷,這樣的化時間復(fù)雜度肯定就是O(N^2)了這就是暴力,但是我不要忘了應(yīng)該怎么判斷重復(fù)字符,看肯定看的出來,可是對于計算機我們就要記錄一下字符了,所以我們就要運用到哈希表了。

解題方法

對于思路中的暴力解法,我們是可以做到很多優(yōu)化的,運用“滑動窗口”,使得時間復(fù)雜度變?yōu)镺(N)。
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享
我們利用“滑動窗口”,來保證窗口中的元素一定不會重復(fù)就可以了,為了實現(xiàn)這個操作我們需要定義應(yīng)該哈希表。因為這里的數(shù)據(jù)全是字符,所以我們可以用int數(shù)組來映射就可以了。
然后就是滑動窗口的經(jīng)典操作:
滑動窗口最重要的操作就是進窗口(移動right)判斷 出窗口(移動left) 更新結(jié)果

Code

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.size();
        int len = 0;
        int hash[128] = {0};
        for(int left = 0,right = 0;right<n;++right)//進窗口
        {
            hash[s[right]]++;
            while(hash[s[right]]>1)
            {
                hash[s[left]]--;
                left++;//出窗口
            }
            len = max(len,right-left+1);//更新結(jié)果
        }
        return len;
    }
};

3.最大連續(xù)1的個數(shù) III(medium)

題目鏈接:最大連續(xù)1的個數(shù) III
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

如果我們只是尋找最長的子字符串1,要考慮的東西就太多了。為了讓這個題目更加的簡單,我們應(yīng)該采用一種正難則反的思想,我們把問題轉(zhuǎn)化為尋找不超過k個0的最長子串。這樣做就簡單的多了,所以在寫編程題的時候如果一點想法都沒有不妨換個角度來想問題。

解題方法

當(dāng)我們把問題簡化之后,滑動窗口的想法就呼之欲出了,和前面一樣,我們要做的就是維護窗口里的元素。這次呢,我們要維護的就是窗口內(nèi)0元素不能超過k個。在此基礎(chǔ)上我們再運用滑動窗口的公式就可以解決問題了:進窗口(移動right)判斷 出窗口(移動left) 更新結(jié)果。

Code

class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        //正難則反,我們把問題轉(zhuǎn)化為尋找不超過k個0的最長子串。
        int zero = 0,len = -1;
        for(int left = 0,right = 0;right<nums.size();++right)//進窗口
        {
            if(nums[right]==0) zero++;
            while(zero>k)//條件判斷
            {
                if(nums[left]==0) zero--;
                left++;//出窗口
            }
            if(zero == k)len = max(len,right-left+1);//更新結(jié)果
        }
        return len==-1?nums.size():len;
    }
};

4.將x減到0的最小操作數(shù)(medium)

題目鏈接:將x減到0的最小操作數(shù)
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

同樣的,直接寫太麻煩了,要考慮的東西太過。還是正難則反,把問題轉(zhuǎn)化一下不就變成了求目標(biāo)值為sum-x最長子數(shù)組和,和第一題不就差不多了嗎?

解題方法

和第一題類似,運用滑動窗口解決,不過再滑動窗口操作之前我們要判斷一下sum-x是否為負數(shù)如果為負數(shù)的話,后面代碼就會溢出的。了解完成后還是那四步:進窗口(移動right)判斷 出窗口(移動left) 更新結(jié)果。

Code

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        //正難則反,表面上讓你找讓x減小到0的最小操作數(shù),實際是可以轉(zhuǎn)化為求目標(biāo)值為sum-x最長子數(shù)組和。
        int sum = 0;
        for(auto num:nums) sum+=num;
        int tar = sum-x;
        if(tar<0)
        return -1;
        int sum_ = 0,res = -1;
        for(int left = 0,right = 0;right<nums.size();++right)//進窗口
        {
            sum_+=nums[right];
            while(sum_>tar)//條件判斷
            {
                sum_-=nums[left++];//出窗口
            }
            if(sum_==tar) res = max(res,right-left+1);//結(jié)果更新
        }
        return res == -1?res: nums.size()-res;
    }
};

5.水果成籃(medium)

題目鏈接:水果成籃
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

這道題的題目有點長,把他翻譯翻譯就是求最長不超過兩類樹的子數(shù)組。了解的這個,這道題就變得簡單了。至于如何判斷是否超過了兩類樹,又要用到哈希表了。

解題方法

寫題的關(guān)將就在于理解題目,我們要把題目轉(zhuǎn)化成我們熟悉的題目。就像這道題,轉(zhuǎn)化后就自然而然地想到了我們滑動窗口。不過就是再加上一個哈希表。我們建立一個哈希數(shù)組,在建立一個kinds來判斷窗口內(nèi)樹地種類。如何判斷呢?
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

Code

class Solution {
public:
    int totalFruit(vector<int>& fruits) {
        //題目可能有點難懂,翻譯一下就求最長不超過兩類樹的子數(shù)組。
        int hash[100001] = {0};
        int kinds = 0,n = fruits.size(),len = 0;
        for(int left = 0,right = 0;right<n;++right)//進窗口
        {
            if(hash[fruits[right]]++==0) kinds++;
            while(kinds>2)//條件判斷
            {
                if(--hash[fruits[left]]==0) kinds--;
                left++;//出窗口
            }
            len = max(len,right-left+1);//更新結(jié)果
        }
        return len;
    }
};

6.找到字符串中所有字母異位詞(medium)

題目鏈接:找到字符串中所有字母異位詞
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

剛上手可能沒想法,那就嘗試暴力解法吧,依次遍歷字符串以示例1為例。
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享
暴力加哈希可以解決但時間復(fù)雜度太高。

解題方法

優(yōu)化上面的暴力方法就需要滑動窗口了。不過這里我們著重要講的是如何利用哈希表來出來這種情況。我們定義了兩個哈希表。一個哈希1用來存放p字符串中的字符。哈希表2就用來存放s字符串里的字符。我們該如何判斷窗口內(nèi)的元素都是p中的呢?

方法一(直接比較哈希表)

因為字符串都是小寫字母,每次我們窗口里有p.size()的字符時我們就比較兩個哈希表,雖然每次比較都要遍歷哈希表,但是小寫字母只有26個時間復(fù)雜度度也就O(26*n)也是常數(shù)級別的可以忽略。

Code

class Solution {
public:
bool check(vector<int>hash,vector<int>hash_1)
{
    for(int i = 0;i<26;++i)
    {
        if(hash[i]!=hash_1[i]) return false;
    }
    return true;
}
    vector<int> findAnagrams(string s, string p) {
        int n_p = p.size();
        vector<int> hash_1(26,0);
        for(auto tmp:p) hash_1[tmp-'a']++;
        int n = s.size();
        int left = 0,right = 0;
        vector<int>hash(26,0);
        vector<int>res;
        while(right<n)
        {
            hash[s[right]-'a']++;
            if(right>=n_p-1)
            {
                if(check(hash,hash_1))
                res.push_back(left);
                hash[s[left]-'a']--;
                left++;
            }
            right++;
        }
        return res;
    }
};

方法二(更優(yōu))

我們利用一個count來記錄窗口內(nèi)p中字符串的個數(shù)。是p中的字符count就++,后續(xù)的出窗口也是如此,是p中的字符就count–。 這個方法的時間復(fù)雜度就是O(N)了

Code

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int hash_1[26] = {0};
        int hash[26] = {0};
        for(auto ch:p) hash_1[ch-'a']++;
        int count = 0,n = s.size();
        vector<int> res;
        for(int left = 0,right = 0;right<n;++right)//進窗口
        {
            if(++hash[s[right]-'a']<=hash_1[s[right]-'a']) count++;
            if(right-left+1>=p.size())//條件判斷
            {
                if(count==p.size()) res.push_back(left);//更新結(jié)果
                if(hash[s[left]-'a']--<=hash_1[s[left]-'a']) count--;
                left++;//出窗口
            }
        }
        return res;
    }
};

7.串聯(lián)所有單詞的子串(hard)

題目鏈接:串聯(lián)所有單詞的子串
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

這題和上面的那道題是差不多的,把字符改成了字符串了,這樣的話我們之前的數(shù)組映射就不好用了。但是我們可以借助一個容器unordered_map。不過還有一點的不同,我們遍歷的次數(shù)發(fā)生了改變。

解題方法

在次數(shù)上的改變體現(xiàn)在因為現(xiàn)在是字符串了。len(word[0].size())
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享
還要注意的就是因為現(xiàn)在是字符串,所以我們的right和left可就是加len個長度了。

Code

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        unordered_map<string,int> hash_1;
        for(auto tmp:words) hash_1[tmp]++;
        int len = words[0].size(),n = s.size();
        vector<int>res;
        for(int i = 0;i<len;++i)
        {
            unordered_map<string,int> hash;
            int count = 0;
            for(int left = i,right = i;right+len<=n;right+=len)//入窗口
            {
                string in = s.substr(right,len);
                if(hash_1[in]&&++hash[in]<=hash_1[in]) count++;
                if(right-left+len>=words.size()*len)//條件判斷
                {
                    if(count==words.size()) res.push_back(left);//結(jié)果更新
                    string out = s.substr(left,len);
                    if(hash_1[out]&&hash[out]--<=hash_1[out]) count--;
                    left+=len;//出窗口
                }
            }
        }
        return res;
    }
};

8.最小覆蓋子串(hard)

題目鏈接:最小覆蓋子串
題目描述
假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享

思路

和前面兩題類似,大體上的步驟都一樣。

解題方法

可以和前面兩題用相似的寫法,定義兩個哈希表。然后用count來判斷窗口內(nèi)是否包含全部的t中元素。雖然我們的返回條件變啦。但是我們也可以不需要創(chuàng)建一個string來存儲最小的覆蓋子串,我們可以利用substr這個成員函數(shù),只需要我們記錄一下初始的位置和長度就可以了。來試試吧。

Code

class Solution {
public:
    string minWindow(string s, string t) {
        int hash_1[128] = {0};
        int hash[128] = {0};
        for(auto ch:t) hash_1[ch]++;
        int n = s.size(),count = 0,len = INT_MAX,begin = 0;
        for(int left = 0,right = 0;right<n;++right)//進窗口
        {
            if(++hash[s[right]]<=hash_1[s[right]]) count++;
            while(count>=t.size())//條件判斷
            {
                int old = len;
                len = min(len,right-left+1);//結(jié)果更新
                if(old!=len) begin = left;
                if(hash[s[left]]--<=hash_1[s[left]]) count--;
                left++;//出窗口
            }
        }
        return len==INT_MAX?"":s.substr(begin,len);
    }
};

總結(jié)規(guī)律

不知道你有沒有發(fā)現(xiàn),我們的滑動窗口的代碼都差不多。我也是把每一道題都重新寫了一遍然后寫成了一樣的格式。

for(int left = 0,right = 0;right<n;++right)//進窗口
        {
            if(++hash[s[right]]<=hash_1[s[right]]) count++;
            while(count>=t.size())//條件判斷
            {
                int old = len;
                len = min(len,right-left+1);//結(jié)果更新
                if(old!=len) begin = left;
                if(hash[s[left]]--<=hash_1[s[left]]) count--;
                left++;//出窗口
            }
        }

全是一層for循環(huán)來遍歷數(shù)組,里面的判斷肯是while循環(huán)也可能是if這取決于你要判斷的次數(shù),然后我們的出窗口都是在判斷里面的,至于結(jié)果更新只有他的位置是變化的,所以我們在寫代碼前就要看看結(jié)果在哪里更新,這樣的話滑動窗口的問題就都可以解決了。

那么本篇博客就到這里結(jié)束了,如果存在錯誤希望得到您的指正。


假期算法提升(帶你徹底掌握滑動窗口),算法,算法,c++,筆記,經(jīng)驗分享文章來源地址http://www.zghlxwxcb.cn/news/detail-836782.html

到了這里,關(guān)于假期算法提升(帶你徹底掌握滑動窗口)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • RecyclerView 滑動布局源碼分析:帶你深入掌握列表滑動機制

    作者:maxcion 現(xiàn)在 RV 已經(jīng)初始化好了,那當(dāng)我們進行滑動交互時代碼又是如何執(zhí)行的呢? RV 優(yōu)秀就優(yōu)秀在他是動態(tài)布局的,與 ScrollView 不同在于: ScrollView 是初始化時將所有child都 inflate 并 add 而 RV 是只 inflate 屏幕展示得下的child. 如果我們有100個child: ScrollView 便會在初始化時就

    2023年04月23日
    瀏覽(22)
  • 一篇文章,帶你徹底掌握接口測試!

    一、什么是接口測試? 所謂接口,是指同一個系統(tǒng)中模塊與模塊間的數(shù)據(jù)傳遞接口、前后端交互、跨系統(tǒng)跨平臺跨數(shù)據(jù)庫的對接。而接口測試,則是通過接口的不同情況下的輸入,去對比輸出,看看是否滿足接口規(guī)范所規(guī)定的功能、安全以及性能方面的要求。 二、為什么要

    2024年02月10日
    瀏覽(34)
  • 萬字詳解,帶你徹底掌握 WebSocket 用法(至尊典藏版)

    萬字詳解,帶你徹底掌握 WebSocket 用法(至尊典藏版)

    1.1 什么是WebSocket WebSocket是一種協(xié)議,用于在Web應(yīng)用程序和服務(wù)器之間建立實時、雙向的通信連接。 它通過一個單一的TCP連接提供了持久化連接,這使得Web應(yīng)用程序可以更加實時地傳遞數(shù)據(jù)。 WebSocket協(xié)議最初由W3C開發(fā),并于2011年成為標(biāo)準(zhǔn)。 1.2 WebSocket的優(yōu)勢和劣勢 WebSocket的

    2024年04月11日
    瀏覽(19)
  • 數(shù)據(jù)結(jié)構(gòu)與算法之美學(xué)習(xí)筆記:41 | 動態(tài)規(guī)劃理論:一篇文章帶你徹底搞懂最優(yōu)子結(jié)構(gòu)、無后效性和重復(fù)子問題

    數(shù)據(jù)結(jié)構(gòu)與算法之美學(xué)習(xí)筆記:41 | 動態(tài)規(guī)劃理論:一篇文章帶你徹底搞懂最優(yōu)子結(jié)構(gòu)、無后效性和重復(fù)子問題

    本節(jié)課程思維導(dǎo)圖: 今天,我主要講動態(tài)規(guī)劃的一些理論知識。學(xué)完這節(jié)內(nèi)容,可以幫你解決這樣幾個問題:什么樣的問題可以用動態(tài)規(guī)劃解決?解決動態(tài)規(guī)劃問題的一般思考過程是什么樣的?貪心、分治、回溯、動態(tài)規(guī)劃這四種算法思想又有什么區(qū)別和聯(lián)系? 什么樣的問

    2024年02月02日
    瀏覽(38)
  • 【算法】基礎(chǔ)算法002之滑動窗口(一)

    【算法】基礎(chǔ)算法002之滑動窗口(一)

    ?? 樊梓慕: 個人主頁 ??? 個人專欄: 《C語言》 《數(shù)據(jù)結(jié)構(gòu)》 《藍橋杯試題》 《LeetCode刷題筆記》 《實訓(xùn)項目》 《C++》 《Linux》《算法》 ?? 每一個不曾起舞的日子,都是對生命的辜負 目錄 前言 1.長度最小的子數(shù)組 滑動窗口類問題解題思路大綱: 2.無重復(fù)字符的最長

    2024年02月19日
    瀏覽(28)
  • 【算法】基礎(chǔ)算法002之滑動窗口(二)

    【算法】基礎(chǔ)算法002之滑動窗口(二)

    ?? 樊梓慕: 個人主頁 ??? 個人專欄: 《C語言》 《數(shù)據(jù)結(jié)構(gòu)》 《藍橋杯試題》 《LeetCode刷題筆記》 《實訓(xùn)項目》 《C++》 《Linux》 《算法》 ?? 每一個不曾起舞的日子,都是對生命的辜負 目錄 前言 ?5.水果成籃(medium) ?6.找到字符串中所有字母異位詞 7.串聯(lián)所有單詞的

    2024年02月20日
    瀏覽(22)
  • LeetCode算法小抄--滑動窗口算法

    ?申明: 未經(jīng)許可,禁止以任何形式轉(zhuǎn)載,若要引用,請標(biāo)注鏈接地址。 全文共計6244字,閱讀大概需要3分鐘 ??更多學(xué)習(xí)內(nèi)容, 歡迎??關(guān)注??文末我的個人微信公眾號:不懂開發(fā)的程序猿 個人網(wǎng)站:https://jerry-jy.co/ 滑動窗口算法 思路 1、我們在字符串 S 中使用雙指針中的

    2023年04月09日
    瀏覽(25)
  • 滑動窗口算法

    目錄 滑動窗口算法 基本思想 ?可解決問題 應(yīng)用 題目一:最小覆蓋子串 題目解讀: ?代碼 題目二:長度最小的子數(shù)組 題目解讀 代碼 滑動算法窗口的優(yōu)缺點 優(yōu)點: 缺點: 首先介紹一下什么是滑動窗口:滑動窗口算法是一種在數(shù)組或字符串中尋找特定模式的算法,它可以在

    2024年02月03日
    瀏覽(18)
  • 算法——滑動窗口

    算法——滑動窗口

    滑動窗口大致分為兩類:一類是窗口長度固定的,即left和right可以一起移動;另一種是窗口的長度變化(例如前五道題),即right瘋狂移動,left沒怎么動,這類題需要觀察單調(diào)性(即指針)等各方面因素綜合思考 長度最小的子數(shù)組 子數(shù)組需要為連續(xù)的區(qū)間 需要在滿足條件的前

    2024年04月10日
    瀏覽(29)
  • 算法習(xí)題之滑動窗口

    滑動窗口是什么? 滑動窗口是一種想象出來的數(shù)據(jù)結(jié)構(gòu): 滑動窗口有左邊界L和有邊界R 在數(shù)組或者字符串或者一個序列上,記為S,窗口就是S[L…R]這一部分 L往右滑意味著一個樣本出了窗口,R往右滑意味著一個樣本進了窗口 L和R都只能往右滑 滑動內(nèi)最大值和最小值的更新結(jié)

    2023年04月15日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包