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

算法:分治思想處理歸并遞歸問題

這篇具有很好參考價(jià)值的文章主要介紹了算法:分治思想處理歸并遞歸問題。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

算法原理

利用歸并思想進(jìn)行分治也是很重要的一種思路,在解決逆序?qū)Φ膯栴}上有很大的需求空間

于是首先歸并排序是首先的,歸并排序要能寫出來:

class Solution 
{
    vector<int> tmp;
public:
    vector<int> sortArray(vector<int>& nums) 
    {
        tmp.resize(nums.size());
        mergesort(nums,0,nums.size()-1);
        return nums;
    }

    void mergesort(vector<int>& nums,int left,int right)
    {
        if(left>=right)
        {
            return;
        }
        // 數(shù)組劃分 [left,mid][mid+1,right]
        int mid=(left+right)/2;

        // 分塊排序
        mergesort(nums,left,mid);
        mergesort(nums,mid+1,right);
    
        // 合并數(shù)組
        int cur1=left,cur2=mid+1,i=0;
        while(cur1<=mid && cur2<=right)
        {
            if(nums[cur1]<=nums[cur2])
            {
                tmp[i++]=nums[cur1++];
            }
            else
            {
                tmp[i++]=nums[cur2++];
            }
        }
        while(cur1<=mid)
        {
            tmp[i++]=nums[cur1++];
        }
        while(cur2<=right)
        {
            tmp[i++]=nums[cur2++];
        }

        for(int i=left;i<=right;i++)
        {
            nums[i]=tmp[i-left];
        }
    }
};

以上為歸并排序基本算法原理,基于這個(gè)原理可以解決逆序?qū)栴},逆序?qū)栴}通常問法是,給定某一個(gè)數(shù)據(jù),在整個(gè)數(shù)組中找比這個(gè)數(shù)大或者比這個(gè)數(shù)小的數(shù),統(tǒng)計(jì)這樣的元素有多少個(gè),進(jìn)而返回到數(shù)組或者直接輸出

那么在找尋這個(gè)過程中,這類問題的基本思路就是:左邊找,右邊找,左右找

在找尋的過程中需要注意的是升序和逆序問題,后續(xù)的題目中會(huì)有涉及到的地方,在這里不過總結(jié)

實(shí)現(xiàn)思路

大體的實(shí)現(xiàn)思路如上,總結(jié)下來就是劃分為兩個(gè)子區(qū)間,在左邊找,在右邊找,接著左右找,這樣就能找到要求的結(jié)果

典型例題

排序數(shù)組

算法:分治思想處理歸并遞歸問題,C++,# 算法,習(xí)題集,算法,數(shù)據(jù)結(jié)構(gòu)

理解快速排序和歸并排序思維的不同點(diǎn)

依舊是經(jīng)典的排序數(shù)組問題,這次選用歸并排序來解決,要了解歸并排序和快速排序其實(shí)都是利用了分治的思想,把一個(gè)很復(fù)雜的問題分解為一個(gè)一個(gè)的小問題,二者在思維上有一些小小的區(qū)別,快速排序的思想是,對(duì)于某個(gè)區(qū)間來說,把這個(gè)區(qū)間進(jìn)行分塊,每一個(gè)分塊都進(jìn)行排序,每一個(gè)都進(jìn)行排序,這樣就完成了目的,這樣的思維更像是一種前序遍歷,完成了這次的任務(wù)后再向后進(jìn)行延伸,而歸并排序的思路和快速排序不同,歸并排序的思路主要是把數(shù)組拆分成一個(gè)一個(gè)的小區(qū)間,不停的拆分,直到不能拆分后再進(jìn)行組裝,它的排序過程整體上而言是滯后的,更像是一種后序遍歷的思想,先一直向深處找,直到找不下去了再進(jìn)行排序,再一層一層向上走

class Solution 
{
    vector<int> tmp;
public:
    vector<int> sortArray(vector<int>& nums) 
    {
        tmp.resize(nums.size());
        mergesort(nums,0,nums.size()-1);
        return nums;
    }

    void mergesort(vector<int>& nums,int left,int right)
    {
        if(left>=right)
        {
            return;
        }
        // 數(shù)組劃分 [left,mid][mid+1,right]
        int mid=(left+right)/2;

        // 分塊排序
        mergesort(nums,left,mid);
        mergesort(nums,mid+1,right);
    
        // 合并數(shù)組
        int cur1=left,cur2=mid+1,i=0;
        while(cur1<=mid && cur2<=right)
        {
            if(nums[cur1]<=nums[cur2])
            {
                tmp[i++]=nums[cur1++];
            }
            else
            {
                tmp[i++]=nums[cur2++];
            }
        }
        while(cur1<=mid)
        {
            tmp[i++]=nums[cur1++];
        }
        while(cur2<=right)
        {
            tmp[i++]=nums[cur2++];
        }

        for(int i=left;i<=right;i++)
        {
            nums[i]=tmp[i-left];
        }
    }
};

數(shù)組中的逆序?qū)?/h3>

算法:分治思想處理歸并遞歸問題,C++,# 算法,習(xí)題集,算法,數(shù)據(jù)結(jié)構(gòu)
利用歸并排序求逆序?qū)κ墙鉀Q這類問題的常見方法,對(duì)于這個(gè)題來說,就可以采用分治的方法來解決問題

具體來說,可以把整個(gè)問題拆分為幾個(gè)小步驟,把當(dāng)前所在區(qū)間分成兩個(gè)區(qū)間,在左邊的區(qū)間內(nèi)找符合逆序?qū)Φ膶?duì)數(shù),再在右邊的區(qū)間內(nèi)找符合逆序?qū)Φ膶?duì)數(shù),同時(shí)把左右兩區(qū)間都進(jìn)行排序,這樣就可以在左右區(qū)間內(nèi)都尋找符合要求的逆序?qū)?shù),這就是一個(gè)輪回思路,把整個(gè)數(shù)組拆分為一個(gè)一個(gè)小區(qū)間即可解決問題,這就是分治的思想

那么思路就確認(rèn)了:

  1. 從左邊數(shù)組中找符合要求的逆序?qū)?/li>
  2. 從右邊數(shù)組中找符合要求的逆序?qū)?/li>
  3. 從左右兩邊數(shù)組中找符合要求的逆序?qū)?/li>

從排列組合的分類原理來看,這樣就能找到所有的逆序?qū)?/p>

從優(yōu)化角度來講,第三步是可以進(jìn)行優(yōu)化的,這就引入了要排序的原因:

如何從左右兩數(shù)組中找逆序?qū)?shù)?

其實(shí)利用雙指針的思想就可以解決,定義cur1和cur2分別指向左右兩個(gè)數(shù)組,假設(shè)這里是提前排序好的,升序的數(shù)組,那么當(dāng)cur1所指向的元素大于cur2所指的元素,那么cur2所指向的元素之前的元素全部滿足條件,因此一次可以找出很多相同的元素,這也是這個(gè)算法的原理

因此這里就引出了為什么要進(jìn)行排序,左右子區(qū)間排序后就可以通過上面的算法快速找到有多少滿足要求的逆序?qū)?/p>

處理剩余元素

  • 如果是左邊出現(xiàn)剩余,說明左邊剩下的所有元素都是?右邊元素?的,但是它們都是已經(jīng)被計(jì)算過的,因此不會(huì)產(chǎn)?逆序?qū)Γ瑑H需歸并排序即可。

  • 如果是右邊出現(xiàn)剩余,說明右邊剩下的元素都是?左邊?的,不符合逆序?qū)Φ亩x,因此也不需要處理,僅需歸并排序即可。

class Solution 
{
    vector<int> tmp;
public:    

    int reversePairs(vector<int>& nums) 
    {
        tmp.resize(50001);
        return mergesort(nums,0,nums.size()-1);
    }

    int mergesort(vector<int>& nums,int left,int right)
    {
        if(left>=right)
        {
            return 0;
        }

        int ret=0,mid=(left+right)/2;

        ret+=mergesort(nums,left,mid);
        ret+=mergesort(nums,mid+1,right);

        int cur1=left,cur2=mid+1,i=0;
        while(cur1<=mid && cur2<=right)
        {
            if(nums[cur1]<=nums[cur2])
            {
                tmp[i++]=nums[cur1++];
            }
            else
            {
                ret+=mid-cur1+1;
                tmp[i++]=nums[cur2++];
            }
        }

        while(cur1<=mid)
        {
            tmp[i++]=nums[cur1++];
        }
        while(cur2<=right)
        {
            tmp[i++]=nums[cur2++];
        }

        for(int i=left;i<=right;i++)
        {
            nums[i]=tmp[i-left];
        }

        return ret;
    }
};

總體來說還是一道有思維量的hard題目,但如果掌握了分治的思想,再去下手就會(huì)容易許多

而這樣的算法的時(shí)間復(fù)雜度也是很優(yōu)秀的,時(shí)間復(fù)雜度是O(N)

計(jì)算右側(cè)小于當(dāng)前元素的個(gè)數(shù)

算法:分治思想處理歸并遞歸問題,C++,# 算法,習(xí)題集,算法,數(shù)據(jù)結(jié)構(gòu)

有了上面的題目的思維鋪墊,解法還是比較好想的,原理就是利用歸并排序進(jìn)行分治的思想

但這個(gè)題和上面的問題也有區(qū)別,由于返回的是數(shù)組,因此需要記錄nums中每一個(gè)數(shù)組中元素在返回?cái)?shù)組中元素的下標(biāo),需要一一對(duì)應(yīng)起來,這是比較關(guān)鍵的一步,也就是說,每次找到符合條件的數(shù)后,這個(gè)數(shù)應(yīng)該被放到返回?cái)?shù)組中的哪個(gè)位置?這就需要用一個(gè)輔助數(shù)組來記錄原數(shù)組中每一個(gè)元素的下標(biāo)所在的位置,這樣就能找到了

class Solution 
{
    vector<int> ret;
    vector<int> index;
    int tmpnums[500010];
    int tmpindex[500010];
public:
    vector<int> countSmaller(vector<int>& nums) 
    {
        int n=nums.size();
        ret.resize(n);
        index.resize(n);
        for(int i=0;i<n;i++)
        {
            index[i]=i;
        }
        mergesort(nums,0,n-1);
        return ret;
    }

    void mergesort(vector<int>& nums,int left,int right)
    {
        if(left>=right)
        {
            return;
        }

        int mid=(left+right)/2;
        mergesort(nums,left,mid);
        mergesort(nums,mid+1,right);

        int cur1=left,cur2=mid+1,i=0;
        while(cur1<=mid && cur2<=right)
        {
            if(nums[cur1]<=nums[cur2])
            {
                tmpnums[i]=nums[cur2];
                tmpindex[i++]=index[cur2++];
            }
            else
            {
                ret[index[cur1]]+=right-cur2+1;
                tmpnums[i]=nums[cur1];
                tmpindex[i++]=index[cur1++];
            }
        }

        while(cur1<=mid)
        {
            tmpnums[i]=nums[cur1];
            tmpindex[i++]=index[cur1++];
        }
        while(cur2<=right)
        {
            tmpnums[i]=nums[cur2];
            tmpindex[i++]=index[cur2++];
        }

        for(int j=left;j<=right;j++)
        {
            nums[j]=tmpnums[j-left];
            index[j]=tmpindex[j-left];
        }
    }
};

總結(jié)

歸并遞歸解決分治問題主要依托于歸并排序,在掌握歸并的前提下找到歸并過程中要找的關(guān)鍵信息文章來源地址http://www.zghlxwxcb.cn/news/detail-691574.html

到了這里,關(guān)于算法:分治思想處理歸并遞歸問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 考研算法31天:歸并排序 【歸并排序,分治】

    考研算法31天:歸并排序 【歸并排序,分治】

    算法介紹 歸并算法其過程分為三步: 1.分:遞歸到最下面 2.治:兩個(gè)元素之間排序。 3。歸:遞歸到最下層然后返回,從兩個(gè)元素變成四個(gè)元素再排序。 如下圖所示: 動(dòng)態(tài)圖如下: 算法題目 算法ac代碼:

    2024年02月11日
    瀏覽(22)
  • 【算法系列篇】分治-歸并

    【算法系列篇】分治-歸并

    上一篇算法文章,我們介紹了分治-快排的算法,今天我將為大家分享關(guān)于分治的另外一種算法——?dú)w并。 歸并算法是一種常用的排序算法,它采用分治策略將待排序的數(shù)組分解為更小的子數(shù)組,然后逐步合并這些子數(shù)組以獲得最終的有序數(shù)組。歸并排序的主要思想是將兩個(gè)

    2024年02月09日
    瀏覽(24)
  • C++算法 —— 分治(2)歸并

    C++算法 —— 分治(2)歸并

    本篇前提條件是已學(xué)會(huì)歸并排序 912. 排序數(shù)組 排序數(shù)組也可以用歸并排序來做。 劍指 Offer 51. 數(shù)組中的逆序?qū)?如果暴力枚舉,一定是可以解決問題的,但肯定不用這個(gè)解法。選擇逆序?qū)Γ梢韵劝褦?shù)組分成兩部分,左半部分 + 右半部分的逆序?qū)?,以及再找左半部分的?shù)字和

    2024年02月10日
    瀏覽(22)
  • 算法基礎(chǔ)15 —— 分治算法(歸并排序 + 快速排序)

    算法基礎(chǔ)15 —— 分治算法(歸并排序 + 快速排序)

    分治法的基本概念、思想 分治法是一種很重要的算法。 字面解釋,分治分治,分而治之。就是把一個(gè)復(fù)雜的問題分成兩個(gè)或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最后子問題可以簡單的直接求解,原問題的解即子問題的解的合并。 不難發(fā)現(xiàn),分

    2024年02月03日
    瀏覽(22)
  • 歸并算法:分治而治的高效算法大揭秘(圖文詳解)

    歸并算法:分治而治的高效算法大揭秘(圖文詳解)

    ?? 鴿芷咕 :個(gè)人主頁 ??? 個(gè)人專欄 : 《數(shù)據(jù)結(jié)構(gòu)算法》《粉絲福利》 ??生活的理想,就是為了理想的生活! 歸并算法是我們算法中最常見的算法之一,其思想非常巧妙。本身歸并是只能歸并有序數(shù)組但是當(dāng)我們利用了二路歸并分治法之后,就可以使用歸并的思想來幫我

    2024年02月03日
    瀏覽(21)
  • 算法導(dǎo)論【分治思想】—大數(shù)乘法、矩陣相乘、殘缺棋盤

    算法導(dǎo)論【分治思想】—大數(shù)乘法、矩陣相乘、殘缺棋盤

    在分而治之的方法中,一個(gè)問題被劃分為較小的問題,然后較小的問題被獨(dú)立地解決,最后較小問題的解決方案被組合成一個(gè)大問題的解決。 通常,分治算法有三個(gè)部分: 分解:將問題劃分為若干子問題,這些子問題是同一問題的較小實(shí)例。 解決:通過遞歸地解決子問題來

    2024年02月03日
    瀏覽(24)
  • 【排序算法】 歸并排序詳解!深入理解!思想+實(shí)現(xiàn)!

    【排序算法】 歸并排序詳解!深入理解!思想+實(shí)現(xiàn)!

    ?? 嶼小夏 : 個(gè)人主頁 ??個(gè)人專欄 : 算法—排序篇 ?? 莫道桑榆晚,為霞尚滿天! ? 什么是歸并?通過歸并排序就能讓數(shù)據(jù)有序?分治法是怎么在歸并排序上應(yīng)用的?本文將對(duì)歸并排序進(jìn)行細(xì)致入微的講解,庖丁解牛般讓你徹底明白歸并排序! 歸并排序(MERGE-SORT)是建

    2024年02月08日
    瀏覽(24)
  • 【排序算法】 歸并排序詳解!深入理解!思想+源碼實(shí)現(xiàn)!

    【排序算法】 歸并排序詳解!深入理解!思想+源碼實(shí)現(xiàn)!

    ?? 嶼小夏 : 個(gè)人主頁 ??個(gè)人專欄 : 算法—排序篇 ?? 莫道桑榆晚,為霞尚滿天! ? 什么是歸并?通過歸并排序就能讓數(shù)據(jù)有序?分治法是怎么在歸并排序上應(yīng)用的?本文將對(duì)歸并排序進(jìn)行細(xì)致入微的講解,庖丁解牛般讓你徹底明白歸并排序! 歸并排序(MERGE-SORT)是建

    2024年02月06日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】歸并排序詳解:歸并排序算法,歸并排序非遞歸實(shí)現(xiàn)

    【數(shù)據(jù)結(jié)構(gòu)與算法】歸并排序詳解:歸并排序算法,歸并排序非遞歸實(shí)現(xiàn)

    歸并排序是一種經(jīng)典的排序算法,它使用了分治法的思想。下面是歸并排序的算法思想: 遞歸地將數(shù)組劃分成較小的子數(shù)組,直到每個(gè)子數(shù)組的長度為1或者0。 將相鄰的子數(shù)組合并,形成更大的已排序的數(shù)組,直到最終得到一個(gè)完全排序的數(shù)組。 歸并排序的過程可以分為三

    2024年01月22日
    瀏覽(32)
  • 排序算法:歸并排序(遞歸和非遞歸)

    排序算法:歸并排序(遞歸和非遞歸)

    朋友們、伙計(jì)們,我們又見面了,本期來給大家解讀一下有關(guān)排序算法的相關(guān)知識(shí)點(diǎn),如果看完之后對(duì)你有一定的啟發(fā),那么請(qǐng)留下你的三連,祝大家心想事成! C 語 言 專 欄: C語言:從入門到精通 數(shù)據(jù)結(jié)構(gòu)專欄: 數(shù)據(jù)結(jié)構(gòu) 個(gè)? 人? 主? 頁?: stackY、 ? 目錄 1.歸并排序

    2024年02月07日
    瀏覽(17)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包