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

遞歸、搜索與回溯算法(專題一:遞歸)

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

往期文章(希望小伙伴們?cè)诳催@篇文章之前,看一下往期文章)

(1)遞歸、搜索與回溯算法(專題零:解釋回溯算法中涉及到的名詞)【回溯算法入門必看】-CSDN博客

接下來我會(huì)用幾道題,來讓同學(xué)們利用我在專題零中提到的遞歸的宏觀思想來解決這些題目。

目錄

1. 漢諾塔

2.?合并兩個(gè)有序鏈表

3. 反轉(zhuǎn)鏈表

4. 兩兩交換鏈表中的結(jié)點(diǎn)

5. 快速冪

解法一? 暴力循環(huán)

解法二? 不斷拆分

解法三? 利用了二進(jìn)制的特點(diǎn)


1. 漢諾塔

這道題可以說是遞歸最經(jīng)典的題目之一,接下來我們就從這道題入手,重新認(rèn)識(shí)一下遞歸是什么?

力扣題目鏈接

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

解析:

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

?文章來源地址http://www.zghlxwxcb.cn/news/detail-824749.html

總結(jié):我們想知道n個(gè)盤子的次數(shù),記住了,在求解f(n)的時(shí)候,我們直接默認(rèn)f(n - 1)已經(jīng)完了就可以了!這個(gè)在前面已經(jīng)解釋過了,在此不再鰲述。我們將n-1個(gè)盤子當(dāng)作一個(gè)整體:這就是類似于分治求解子問題的思想

那么當(dāng)由3個(gè)盤子時(shí),就有公式:f(3,x,y,z) = f(2,x,z,y),x->z,f(2,y,x,z);當(dāng)有4個(gè)盤子時(shí),就有公式:f(4,x,y,z) = f(3,x,z,y),x->z,f(3,y,x,z).從而推出f(n,x,y,z) = f(n,x,z,y),x->z,f(n,y,x,z)!

綜上所述:也就是說我們想移動(dòng)n個(gè)盤子,就需要先移動(dòng)n - 1個(gè)盤子;移動(dòng)n - 1個(gè)盤子,就需要先移動(dòng)n - 2個(gè)盤子 ………………;移動(dòng)2個(gè)盤子,就必須先移動(dòng)1個(gè)盤子;

(1)而移動(dòng)1個(gè)盤子就是遞歸的終止條件

(2)而n個(gè)盤子變成n - 1個(gè)盤子就是遞歸的大問題變成小問題的方法

宏觀角度分析遞歸:

再來回顧,宏觀的細(xì)節(jié)

  • 一:不要在意遞歸的細(xì)節(jié)展開圖
  • 二:把遞歸的函數(shù)當(dāng)成一個(gè)“黑盒”
  • 三:我們的無條件的相信“黑盒”可以為我們解決當(dāng)前的子問題(再次強(qiáng)調(diào),遞歸中的每個(gè)子問題的解題步驟都是一樣)

具體構(gòu)建一個(gè)遞歸算法:

(1)創(chuàng)建函數(shù)頭 ——> 從重復(fù)子問題入手,將x柱子上的盤子,借助y柱子轉(zhuǎn)移到z柱子上。從而有函數(shù)頭為:dfs(int x,int y,int z,int n); x、y和z代表了柱子,n代表現(xiàn)在多少個(gè)盤子需要移動(dòng)。x是開始柱,y是中轉(zhuǎn)柱,z是目的柱。

(2)確定函數(shù)體 ——> 無條件相信他能幫我們解決每一個(gè)子問題的。

重復(fù)的子問題如下:

  • 如從 x 號(hào)柱子將n - 1個(gè)盤子借助 z 號(hào)柱子移動(dòng)到 y?號(hào)柱子上
  • 將 x 號(hào)柱子將最后一個(gè)盤子移動(dòng)到 z?號(hào)柱子上
  • 將 y?號(hào)柱子上的n - 1個(gè)盤子移動(dòng)到 z?號(hào)柱子上

從而有函數(shù)體為:

① dfs(x,z,y,n - 1); ② x.back -> z; ③ dfs(y,x,z,n - 1);

(3)遞歸出口:當(dāng)剩下一個(gè)盤子的時(shí)候,也就是n == 1時(shí)。x.back -> z即可。

    //宏觀角度分析遞歸
    //1.創(chuàng)建函數(shù)頭
    //2.確定函數(shù)體,無條件相信他能幫我們解決每一個(gè)子問題的
    //3.遞歸出口
    public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
        dfs(A,B,C,A.size());
    }

    public void dfs(List<Integer> x,List<Integer> y,List<Integer> z,int size){
        //遞歸出口
        if(size == 1){
            z.add(x.remove(x.size() - 1));
            return;
        }

        //封裝一個(gè)小黑盒
        //將x柱上的size - 1個(gè)盤子通過z柱子移動(dòng)到y(tǒng)柱子上
        dfs(x,z,y,size - 1);
        //將a柱上的最后一個(gè)盤子移動(dòng)到c柱子上
        z.add(x.remove(x.size() - 1));
        //將b柱上的size - 1個(gè)盤子通過a柱子移動(dòng)到c柱子上
        dfs(y,x,z,size - 1);
    }

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

2.?合并兩個(gè)有序鏈表

力扣題目鏈接

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

解析:
(1)遞歸函數(shù)的含義:交給你兩個(gè)鏈表的頭結(jié)點(diǎn),你幫我把它們合并起來,并且返回合并后的頭結(jié)點(diǎn)。
(2)函數(shù)體:選擇兩個(gè)頭結(jié)點(diǎn)中較?的結(jié)點(diǎn)作為最終合并后的頭結(jié)點(diǎn),然后將剩下的鏈表交給遞歸函數(shù)去處理。
(3)遞歸出?:當(dāng)某?個(gè)鏈表為空的時(shí)候,返回另外?個(gè)鏈表。?

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

    // 法一:遞歸法
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // 遞歸出口:當(dāng)l1或者l2為空,就返回另一個(gè)不為空的鏈表
        if (l1 == null)
            return l2;
        if (l2 == null)
            return l1;
        //如果l1的值小于l2,那么就讓l1作為頭結(jié)點(diǎn),剩下的結(jié)點(diǎn)繼續(xù)比較
        if (l1.val <= l2.val) {
            l1.next = mergeTwoLists(l1.next,l2);
            return l1;
        }
        else{
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

3. 反轉(zhuǎn)鏈表

力扣題目鏈接

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先?

解析:?

(1)遞歸函數(shù)的含義:交給你?個(gè)鏈表的頭指針,你幫我逆序之后,返回逆序后的頭結(jié)點(diǎn)。
(2)函數(shù)體:先把當(dāng)前結(jié)點(diǎn)之后的鏈表逆序,逆序完之后,把當(dāng)前結(jié)點(diǎn)添加到逆序后的鏈表后?即可。(相同的子問題)
(3)遞歸出?:當(dāng)前結(jié)點(diǎn)為空或者當(dāng)前只有?個(gè)結(jié)點(diǎn)的時(shí)候,不?逆序,直接返回。

    public ListNode reverseList(ListNode head) {
        return dfs(head);
    }
    public ListNode dfs(ListNode h){
        //遞歸出口:直接到找最后一個(gè)結(jié)點(diǎn),類似后序遍歷
        if(h == null || h.next == null){
            return h;
        }
        //找最后一個(gè)結(jié)點(diǎn)
        ListNode newNode = dfs(h.next);
        //從倒數(shù)第二個(gè)結(jié)點(diǎn)開始
        h.next.next = h;
        h.next = null;

        return newNode;
    }

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

4. 兩兩交換鏈表中的結(jié)點(diǎn)

力扣題目鏈接

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

解析:

(1)遞歸函數(shù)的含義:交給你?個(gè)鏈表,將這個(gè)鏈表兩兩交換?下,然后返回交換后的頭結(jié)點(diǎn)。
(2)函數(shù)體:先去處理?下第?個(gè)結(jié)點(diǎn)往后的鏈表,然后再把當(dāng)前的兩個(gè)結(jié)點(diǎn)交換?下,連接上后?處理后的鏈表。(相同的子問題)
(3)遞歸出?:當(dāng)前結(jié)點(diǎn)為空或者當(dāng)前只有?個(gè)結(jié)點(diǎn)的時(shí)候,不?交換,直接返回。?

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

    //后序遍歷
    public ListNode swapPairs(ListNode head) {
        //鏈表中節(jié)點(diǎn)的數(shù)目在范圍 [0, 100] 內(nèi)
        //如果只剩下一個(gè)結(jié)點(diǎn)就沒必要交換了,因?yàn)槭莾蓛山粨Q
        if(head == null || head.next == null){
            return head;
        }
        //先去交換在我之后之后的結(jié)點(diǎn)
        ListNode newNode = swapPairs(head.next.next);
        ListNode ret = head.next;
        head.next = newNode;
        ret.next = head;
        return ret;
    }

?要先修改后面結(jié)點(diǎn),再能修改當(dāng)前結(jié)點(diǎn),很類似后序遍歷的方式。

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

5. 快速冪

力扣題目鏈接

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

解法一? 暴力循環(huán)

    public double myPow(double x, int n) {
        double ret = 1;
        int tmp = n;
        if(n < 0) n = -n;
        for(int i = 1;i <= n;i++){
            ret *= x;
        }
        if(tmp < 0) ret = 1.0 / ret;
        return ret;
    }

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

暴力循環(huán)可以解決較小的冪,當(dāng)冪的值比較大就會(huì)報(bào)超時(shí)的錯(cuò)誤?。?!

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

所以有了如下兩個(gè)改進(jìn)方案:

?

解法二? 不斷拆分

(1)遞歸函數(shù)的含義:求出?x 的 n 次?是多少,然后返回。
(2)函數(shù)體:先求出 x 的?n / 2 次?是多少,然后根據(jù)?n 的奇偶,得出?x 的?n 次?是多少。
(3)遞歸出?:當(dāng)?n 為?0 的時(shí)候,返回?1 即可?。

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

    //第二種方法:
    public double myPow(double x, int n) {
        return n < 0 ? 1.0 / pow(x,-n) : pow(x,n);
    }

    public double pow(double x,int n){
        if(n == 0)
            return 1.0;
        double tmp = pow(x,n/2);
        return n % 2 == 0 ? tmp * tmp : tmp * tmp * x;
    }

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

解法三? 利用了二進(jìn)制的特點(diǎn)

例如算:

分解:遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

(1)而、、是倍乘關(guān)系,所以算不用11個(gè)a相乘,而是??得到,,而?得到。

(2)那么問題來了,如何將11分解成 11 = 8 + 2 + 1這樣的倍乘關(guān)系呢?

答:遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

(3)這里因?yàn)槎M(jìn)制的11中第三位為0,所以沒有?,如果跳過4呢?1011中的0,就是需要跳過的 4。

(4)遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

推算乘積:從低位往高位處理1011(右移一次,就把剛處理的低位移走了)

  • 1011,處理末尾的1:計(jì)算a。 ;
  • 1011,處理第2個(gè)1:計(jì)算。?遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先?;
  • 1011,處理0:跳過。
  • 1011,處理1:計(jì)算。?遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先
    //第三種方法:
    public double myPow(double x, int n) {
        double base = x;
        int tmp = n;
        double res = 1;
        if(n < 0) n = -n;
        while(n != 0){
            if((n & 1) != 0) //如果n的最后一位是1,表示這個(gè)地方需要乘
                res*=base;
            base*=base;//推算乘積,在解析有說明
            n>>=1;//n右移一位,把剛處理過n的最后一位去掉
        }
        if(tmp < 0) res = 1.0 / res;
        return res;
    }

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

注:解法三的速度比解法一快了許多,但是相比于解法二還是慢了一些,導(dǎo)致超時(shí)錯(cuò)誤。

遞歸、搜索與回溯算法(專題一:遞歸),Java版本的算法題,回溯算法,算法,java,深度優(yōu)先

?

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

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(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)文章

  • 專題二:二叉樹的深搜【遞歸、搜索、回溯】

    專題二:二叉樹的深搜【遞歸、搜索、回溯】

    深度優(yōu)先遍歷 (DFS,全稱為DepthFirstTraversal),是我們樹或者圖這樣的數(shù)據(jù)結(jié)構(gòu)中常用的?種遍歷算法。這個(gè)算法會(huì)盡可能深的搜索樹或者圖的分?,直到?條路徑上的所有節(jié)點(diǎn)都被遍歷完畢,然后再回溯到上?層,繼續(xù)找?條路遍歷。 在?叉樹中,常?的深度優(yōu)先遍歷為:

    2024年02月07日
    瀏覽(21)
  • 遞歸專題訓(xùn)練詳解(回溯,剪枝,深度優(yōu)先)

    遞歸專題訓(xùn)練詳解(回溯,剪枝,深度優(yōu)先)

    在經(jīng)典漢諾塔問題中,有 3 根柱子及 N 個(gè)不同大小的穿孔圓盤,盤子可以滑入任意一根柱子。一開始,所有盤子自上而下按升序依次套在第一根柱子上(即每一個(gè)盤子只能放在更大的盤子上面)。移動(dòng)圓盤時(shí)受到以下限制: (1) 每次只能移動(dòng)一個(gè)盤子; (2) 盤子只能從柱子頂端滑出

    2024年02月07日
    瀏覽(27)
  • 【算法系列篇】遞歸、搜索與回溯(一)

    【算法系列篇】遞歸、搜索與回溯(一)

    遞歸算法是一種通過重復(fù)將問題分解為同類的子問題而解決問題的方法。遞歸式方法可以被用于解決很多的計(jì)算機(jī)科學(xué)問題,因此它是計(jì)算機(jī)科學(xué)中十分重要的一個(gè)概念。絕大多數(shù)編程語言支持函數(shù)的自調(diào)用,在這些語言中函數(shù)可以通過調(diào)用自身來進(jìn)行遞歸。 搜索算法是利用

    2024年02月04日
    瀏覽(24)
  • 【算法系列篇】遞歸、搜索和回溯(二)

    【算法系列篇】遞歸、搜索和回溯(二)

    前面為大家介紹了關(guān)于遞歸的知識(shí),以及使用遞歸解決了幾個(gè)問題,那么這篇文章將帶大家鞏固一下關(guān)于遞歸的知識(shí)。 https://leetcode.cn/problems/swap-nodes-in-pairs/description/ 給你一個(gè)鏈表,兩兩交換其中相鄰的節(jié)點(diǎn),并返回交換后鏈表的頭節(jié)點(diǎn)。 你必須在不修改節(jié)點(diǎn)內(nèi)部的值的情況

    2024年02月05日
    瀏覽(21)
  • 【算法系列篇】遞歸、搜索和回溯(三)

    【算法系列篇】遞歸、搜索和回溯(三)

    前面我已經(jīng)給大家分享了兩篇關(guān)于遞歸、搜索和回溯相關(guān)的問題,但是前面兩篇只涉及到了遞歸,搜索和回溯基本還沒涉及到,大家先別著急,后面的文章會(huì)為大家分享關(guān)于搜索和回溯相關(guān)的知識(shí)和題目。今天這篇文章主要涉及到的就是關(guān)于在遞歸過程中的剪枝問題。 二叉樹

    2024年02月04日
    瀏覽(20)
  • 【算法系列篇】遞歸、搜索和回溯(四)

    【算法系列篇】遞歸、搜索和回溯(四)

    前面我們通過幾個(gè)題目基本了解了解決遞歸類問題的基本思路和步驟,相信大家對(duì)于遞歸多多少少有了更加深入的了解。那么本篇文章我將為大家分享結(jié)合決策樹來解決遞歸、搜索和回溯相關(guān)的問題。 決策樹是一種基本的分類與回歸方法。在分類問題中,決策樹通過構(gòu)建一棵

    2024年02月04日
    瀏覽(19)
  • Java中常用算法及示例-分治、迭代、遞歸、遞推、動(dòng)態(tài)規(guī)劃、回溯、窮舉、貪心

    Java中常用算法及示例-分治、迭代、遞歸、遞推、動(dòng)態(tài)規(guī)劃、回溯、窮舉、貪心

    1、分治算法的基本思想是將一個(gè)計(jì)算復(fù)雜的問題分成規(guī)模較小、計(jì)算簡(jiǎn)單的小問題求解, 然后綜合各個(gè)小問題,得到最終答案。 2、窮舉(又稱枚舉)算法的基本思想是從所有可能的情況中搜索正確的答案。 3、迭代法(Iterative Method) 無法使用公式一次求解,而需要使用重復(fù)結(jié)構(gòu)

    2024年02月08日
    瀏覽(25)
  • 【課設(shè)】java:迷宮小游戲(遞歸與分治、動(dòng)態(tài)規(guī)劃、貪心算法、回溯法、分支限界法)

    【課設(shè)】java:迷宮小游戲(遞歸與分治、動(dòng)態(tài)規(guī)劃、貪心算法、回溯法、分支限界法)

    魚弦:CSDN內(nèi)容合伙人、CSDN新星導(dǎo)師、全棧領(lǐng)域優(yōu)質(zhì)創(chuàng)作者 、51CTO(Top紅人+專家博主) 、github開源愛好者(go-zero源碼二次開發(fā)、游戲后端架構(gòu) https://github.com/Peakchen) 遞歸與分治算法 原理: 遞歸與分治算法將問題分解為子問題,遞歸地解決每個(gè)子問題,最后將結(jié)果合并得到整

    2024年02月02日
    瀏覽(33)
  • ? ★ 算法基礎(chǔ)筆記(Acwing)(三)—— 搜索與圖論(17道題)【java版本】

    ? ★ 算法基礎(chǔ)筆記(Acwing)(三)—— 搜索與圖論(17道題)【java版本】

    1. 排列數(shù)字(3分鐘) 每次遍歷dfs參數(shù)是 遍歷的坑位 原題鏈接 2. n-皇后問題 原題鏈接 方法 1. 按行遍歷(過程中有回溯、剪枝) 思想: 每次遞歸中,遍歷一行的元素,如果可以放皇后,就遞歸到下一行,下一行中不行了,就返回來,回溯, 方法2. 按每個(gè)元素遍歷(沒有減枝)

    2024年02月05日
    瀏覽(23)
  • 遞歸回溯兩個(gè)例題:1.數(shù)組組合 2.在矩陣中搜索單詞

    遞歸回溯兩個(gè)例題:1.數(shù)組組合 2.在矩陣中搜索單詞

    題目1:組合 給定兩個(gè)整數(shù) n 和 k ,返回范圍 [1, n] 中所有可能的 k 個(gè)數(shù)的組合。 你可以按 任何順序 返回答案。 輸入:n = 4, k = 2 輸出: [ ? [2,4], ? [3,4], ? [2,3], ? [1,2], ? [1,3], ? [1,4], ] ?解題思路: 1.定義一個(gè)temp數(shù)組,存放臨時(shí)的組合結(jié)果 2.兩種選擇:1.選擇當(dāng)前元素2.不選

    2024年02月15日
    瀏覽(21)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包