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

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

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

往期文章(希望小伙伴們在看這篇文章之前,看一下往期文章)

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

(2)遞歸、搜索與回溯算法(專題一:遞歸)-CSDN博客

?深搜是實現(xiàn)遞歸的一種方式,接下來我們之間從題入手,深入淺出地了解深搜吧!

目錄

1. 計算布爾二叉樹的值

2. 求根結(jié)點到葉結(jié)點的數(shù)字之和

3. 二叉樹剪枝

4. 驗證二叉搜索樹

5. 二叉搜索樹中第k小的元素

??6. 二叉樹的所有路徑


1. 計算布爾二叉樹的值

力扣題目鏈接

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

?遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

解析:?

(1)函數(shù)頭設(shè)計

需要根結(jié)點,故函數(shù)頭為:dfs(TreeNode root);

(2)函數(shù)體設(shè)計(無條件相信這個“黑盒”,他能幫你將每個相同的子問題穩(wěn)妥地解決!?。。?/strong>

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

① 接收左子樹傳過來的值:boolean leftTree = dfs(root.left);? ? ? ?

② 接收右子樹傳過來的值:boolean rightTree = dfs(root.right);

③ leftTree ——> root.val <—— rightTree 得到最終結(jié)果。

(3)遞歸出口

到葉子結(jié)點就是應(yīng)該結(jié)束遞歸,開始回溯。

    public boolean evaluateTree(TreeNode root) {
        //遞歸出口
        //到了葉子結(jié)點
        if(root.left == null){
            if(root.val == 0)
                return false;
            else
                return true;
        }
        //開始遞歸
        boolean leftTree = evaluateTree(root.left);
        boolean rightTree = evaluateTree(root.right);
        if(root.val == 2){
            return leftTree || rightTree;
        }else{
            return leftTree && rightTree;
        }
    }

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

2. 求根結(jié)點到葉結(jié)點的數(shù)字之和

力扣題目鏈接

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

解析:

前序遍歷按照根節(jié)點、左?樹、右?樹的順序遍歷?叉樹的所有節(jié)點,通常?于?節(jié)點的狀態(tài)依賴于?節(jié)點狀態(tài)的題?。
在前序遍歷的過程中,我們可以往左右?樹傳遞信息,并且在回溯時得到左右?樹的返回值。遞歸函數(shù)可以幫我們完成兩件事:
(1)將?節(jié)點的數(shù)字與當(dāng)前節(jié)點的信息整合到?起,計算出當(dāng)前節(jié)點的數(shù)字,然后傳遞到下?層進(jìn)?遞
歸;
(2)當(dāng)遇到葉?節(jié)點的時候,就不再向下傳遞信息,?是將整合的結(jié)果向上?直回溯到根節(jié)點。
在遞歸結(jié)束時,根節(jié)點需要返回的值也就被更新為了整棵樹的數(shù)字和。

遞歸函數(shù)設(shè)計:int dfs(TreeNode?root,int num)
(1)返回值:當(dāng)前?樹計算的結(jié)果(數(shù)字和);

(2)參數(shù)num:遞歸過程中往下傳遞的信息(?節(jié)點的數(shù)字);
(3)函數(shù)作?:整合?節(jié)點的信息與當(dāng)前節(jié)點的信息計算當(dāng)前節(jié)點數(shù)字,并向下傳遞,在回溯時返回當(dāng)前?樹(當(dāng)前節(jié)點作為?樹根節(jié)點)數(shù)字和。

遞歸函數(shù)流程:
(1)當(dāng)遇到空節(jié)點的時候,說明這條路從根節(jié)點開始沒有分?,返回0;
(2)結(jié)合?節(jié)點傳下的信息以及當(dāng)前節(jié)點的val,計算出當(dāng)前節(jié)點數(shù)字sum;
(3)如果當(dāng)前結(jié)點是葉?節(jié)點,直接返回整合后的結(jié)果sum;
(4)如果當(dāng)前結(jié)點不是葉?節(jié)點,將?sum?傳到左右?樹中去,得到左右?樹中節(jié)點路徑的數(shù)字和,然后相加后返回結(jié)果。

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

① 將自身的值并入;②??將自己本身的數(shù)字并入后走左子樹;③?將自己本身的數(shù)字并入后走右子樹;④ 左右子樹的結(jié)果,然后向上返回。

    public int sumNumbers(TreeNode root) {
        return dfs(root,0);//從個位數(shù)開始
    }
    public int dfs(TreeNode root,int perSum){
        //一:將自身的值并入
        perSum = perSum * 10 + root.val;
        //四:遞歸出口:看看是不是葉子結(jié)點了,如果是,就向上返回
        if(root.left == null && root.right == null){
            return perSum;
        }
        //二:走左子樹
        int ret = 0;
        if(root.left != null){
            ret += dfs(root.left,perSum);
        }
        //三:走右子樹
        if(root.right != null){
            ret += dfs(root.right,perSum);
        }
        return ret;
    }

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

3. 二叉樹剪枝

力扣題目鏈接

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

解析:

后序遍歷按照左?樹、右?樹、根節(jié)點的順序遍歷?叉樹的所有節(jié)點,通常?于?節(jié)點的狀態(tài)依賴于?節(jié)點狀態(tài)的題?。
(1)如果我們選擇從上往下刪除,我們需要收集左右?樹的信息,這可能導(dǎo)致代碼編寫相對困難。然?,通過觀察我們可以發(fā)現(xiàn),如果我們先刪除最底部的葉?節(jié)點,然后再處理刪除后的節(jié)點,最終的結(jié)果并不會受到影響。
(2)因此,我們可以采?后序遍歷的?式來解決這個問題。在后序遍歷中,我們先處理左?樹,然后處理右?樹,最后再處理當(dāng)前節(jié)點。在處理當(dāng)前節(jié)點時,我們可以判斷其是否為葉?節(jié)點且其值是否為0。如果滿?條件,我們可以刪除當(dāng)前節(jié)點。
? 需要注意的是,在刪除葉?節(jié)點時,其?節(jié)點很可能會成為新的葉?節(jié)點。因此,在處理完?節(jié)點后,我們?nèi)匀恍枰幚懋?dāng)前節(jié)點。這也是為什么選擇后序遍歷的原因(后序遍歷?先遍歷到的?定是葉?節(jié)點)。
? 通過使?后序遍歷,我們可以逐步刪除葉?節(jié)點,并且保證刪除后的節(jié)點仍然滿?刪除操作的要
求。這樣,我們可以較為?便地實現(xiàn)刪除操作,?不會影響最終的結(jié)果。
? 若在處理結(jié)束后所有葉?節(jié)點的值均為1,則所有?樹均包含1,此時可以返回。

遞歸函數(shù)頭設(shè)計:void dfs(TreeNode root)
(1)返回值:?;
(2)參數(shù):當(dāng)前需要處理的節(jié)點;
(3)函數(shù)作?:判斷當(dāng)前節(jié)點是否需要刪除,若需要刪除,則刪除當(dāng)前節(jié)點。

后序遍歷的主要流程(函數(shù)體):

(1)遞歸出?:當(dāng)傳?節(jié)點為空時,不做任何處理;
(2)遞歸處理左?樹;
(3)遞歸處理右?樹;
(4)處理當(dāng)前節(jié)點:判斷該節(jié)點是否為葉?節(jié)點(即左右?節(jié)點均被刪除,當(dāng)前節(jié)點成為葉?節(jié)點),并且節(jié)點的值為0:

  • 如果是,就刪除掉;
  • 如果不是,就不做任何處理。
    public TreeNode pruneTree(TreeNode root) {
        //遞歸出口
        if(root == null){
            return null;
        }
        //判斷左子樹
        root.left = pruneTree(root.left);
        //判斷右子樹
        root.right = pruneTree(root.right);
        //判斷
        if(root.left == null && root.right == null && root.val == 0){
            root = null;
        }
        return root;
    }

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

4. 驗證二叉搜索樹

力扣題目鏈接

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java?

解析:

中序遍歷按照左?樹、根節(jié)點、右?樹的順序遍歷?叉樹的所有節(jié)點,通常?于?叉搜索樹相關(guān)題
?。
(1)如果?棵樹是?叉搜索樹,那么它的中序遍歷的結(jié)果?定是?個嚴(yán)格遞增的序列。
(2)因此,我們可以初始化?個?窮?的全區(qū)變量,?來記錄中序遍歷過程中的前驅(qū)結(jié)點。那么就可以在中序遍歷的過程中,先判斷是否和前驅(qū)結(jié)點構(gòu)成遞增序列,然后修改前驅(qū)結(jié)點為當(dāng)前結(jié)點,傳?下?層的遞歸中。?

算法流程:
(1)初始化?個全局的變量prev,?來記錄中序遍歷過程中的前驅(qū)結(jié)點的val;
(2)中序遍歷的遞歸函數(shù)中:
① 設(shè)置遞歸出?:root == null 的時候,返回true;(葉子結(jié)點本身就是一棵二叉搜索樹)
② 先遞歸判斷左?樹是否是?叉搜索樹,?left標(biāo)記;
③ 然后判斷當(dāng)前結(jié)點是否滿??叉搜索樹的性質(zhì);
? 如果當(dāng)前結(jié)點的val?于prev,說明滿?條件,將prev改為root.val;
? 如果當(dāng)前結(jié)點的val?于等于prev,說明不滿?條件,return false;
最后遞歸判斷右?樹是否是?叉搜索樹,?right標(biāo)記;
(3)只有當(dāng)left和right都是true的時候,才返回true。

    long prev = Long.MIN_VALUE;//存放上一個結(jié)點的值
    public boolean isValidBST(TreeNode root) {
        if(root == null)
            return true;
        
        //遞歸判斷左子樹
        boolean left = isValidBST(root.left);
        if(prev < root.val)
            prev = root.val;
        //判斷當(dāng)前節(jié)點是否為二叉搜索樹,右邊就不需要搞
        else
            return false;
        //剪枝,剪掉右子樹的判斷
        if(left == false)
            return false;
        //遞歸判斷右子樹,告訴父節(jié)點,我不是二叉搜索樹,你也不是
        boolean right = isValidBST(root.right);
        if(left == true && right == true)
            return true;
        else
            return false;
    }

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

?

5. 二叉搜索樹中第k小的元素

力扣題目鏈接?

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

?

解析:

中序遍歷 + 計數(shù)器剪枝

我們可以根據(jù)中序遍歷的過程,只需掃描前k個結(jié)點即可。
因此,我們可以創(chuàng)建?個全局的計數(shù)器count,將其初始化為k,每遍歷?個節(jié)點就將count--。直到某次遞歸的時候,count的值等于1,說明此時的結(jié)點就是我們要找的結(jié)果。

    int ret = 0;//用來存儲最終結(jié)果
    int count;//用來表示要找第幾個結(jié)點
    public int kthSmallest(TreeNode root, int k) {
        count = k;
        dfs(root);
        return ret;
    }
    public void dfs(TreeNode root){
        if(root == null)
            return;
        dfs(root.left);
        count--;
        if(count == 0){
            ret = root.val;
        }
        dfs(root.right);
    }

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

?

6. 二叉樹的所有路徑

力扣題目鏈接?

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java?

解析:

使?深度優(yōu)先遍歷(DFS)求解。
路徑以字符串形式存儲,從根節(jié)點開始遍歷,每次遍歷時將當(dāng)前節(jié)點的值加?到路徑中,如果該節(jié)點為葉?節(jié)點,將路徑存儲到結(jié)果中。否則,將"->"加?到路徑中并遞歸遍歷該節(jié)點的左右?樹。
定義?個結(jié)果數(shù)組,進(jìn)?遞歸。遞歸具體實現(xiàn)?法如下:
(1)如果當(dāng)前節(jié)點不為空,就將當(dāng)前節(jié)點的值加?路徑path中,否則直接返回;
(2)判斷當(dāng)前節(jié)點是否為葉?節(jié)點,如果是,則將當(dāng)前路徑加?到所有路徑的存儲數(shù)組paths中;
(3)否則,將當(dāng)前節(jié)點值加上"->"作為路徑的分隔符,繼續(xù)遞歸遍歷當(dāng)前節(jié)點的左右?節(jié)點;
(4)返回結(jié)果數(shù)組;


注:特別地,我們可以只使??個字符串存儲每個狀態(tài)的字符串,在遞歸回溯的過程中,需要將路徑中的當(dāng)前節(jié)點移除,以回到上?個節(jié)點。

具體實現(xiàn)?法如下:
(1)定義?個結(jié)果數(shù)組和?個路徑數(shù)組。
(2)從根節(jié)點開始遞歸,遞歸函數(shù)的參數(shù)為當(dāng)前節(jié)點、結(jié)果數(shù)組和路徑數(shù)組。
① 如果當(dāng)前節(jié)點為空,返回。
② 將當(dāng)前節(jié)點的值加?到路徑數(shù)組中。
③ 如果當(dāng)前節(jié)點為葉?節(jié)點,將路徑數(shù)組中的所有元素拼接成字符串,并將該字符串存儲到結(jié)果
數(shù)組中。
④ 遞歸遍歷當(dāng)前節(jié)點的左?樹。
⑤ 遞歸遍歷當(dāng)前節(jié)點的右?樹。
⑥ 回溯,將路徑數(shù)組中的最后?個元素移除,以返回到上?個節(jié)點。

    List<String> ret;
    public List<String> binaryTreePaths(TreeNode root) {
        ret = new ArrayList<>();
        dfs(root,new StringBuffer());
        return ret;
    }
    public void dfs(TreeNode root,StringBuffer curPath){
        //起恢復(fù)現(xiàn)場的作用
        StringBuffer path = new StringBuffer(curPath);
        path.append(Integer.toString(root.val));
        if(root.left == null && root.right == null){
            ret.add(path.toString());
            return;
        }
        path.append("->");
        if(root.left != null) dfs(root.left,path);
        if(root.right !=null) dfs(root.right,path);
    }

遞歸、搜索與回溯算法(專題二:深搜),Java版本的算法題,回溯算法,算法,java文章來源地址http://www.zghlxwxcb.cn/news/detail-807806.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ìn)行投訴反饋,一經(jīng)查實,立即刪除!

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

相關(guān)文章

  • 專題一:遞歸【遞歸、搜索、回溯】

    專題一:遞歸【遞歸、搜索、回溯】

    什么是遞歸 函數(shù)自己調(diào)用自己的情況。 為什么要用遞歸 主問題-子問題????????子問題-子問題 宏觀看待遞歸 不要在意細(xì)節(jié)展開圖,把函數(shù)當(dāng)成一個黑盒,相信這個黑盒一定能完成任務(wù)。 ?如何寫好遞歸 ? 分析跟上一題差不多,不詳解。 實現(xiàn)?pow(x,?n)?,即計算? x ?的整

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    【課設(shè)】java:迷宮小游戲(遞歸與分治、動態(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) 遞歸與分治算法 原理: 遞歸與分治算法將問題分解為子問題,遞歸地解決每個子問題,最后將結(jié)果合并得到整

    2024年02月02日
    瀏覽(32)
  • DFS:深搜+回溯+剪枝解決矩陣搜索問題

    DFS:深搜+回溯+剪枝解決矩陣搜索問題

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?創(chuàng)作不易,感謝三連??!? . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) . - 力扣(LeetCode) 1、矩陣搜索問題經(jīng)常要用到向量,也就是我們可以通過dx和dy來幫助我們定義方向

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

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

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

    2024年02月07日
    瀏覽(27)
  • 算法沉淀——窮舉、暴搜、深搜、回溯、剪枝綜合練習(xí)一(leetcode真題剖析)

    算法沉淀——窮舉、暴搜、深搜、回溯、剪枝綜合練習(xí)一(leetcode真題剖析)

    題目鏈接:https://leetcode.cn/problems/permutations/ 給定一個不含重復(fù)數(shù)字的數(shù)組 nums ,返回其 所有可能的全排列 。你可以 按任意順序 返回答案。 示例 1: 示例 2: 示例 3: 提示: 1 = nums.length = 6 -10 = nums[i] = 10 nums 中的所有整數(shù) 互不相同 思路 這是一個典型的回溯問題,需要在每

    2024年02月21日
    瀏覽(23)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包