【寸鐵的刷題筆記】樹、dfs、bfs、回溯、遞歸(一)

【寸鐵的刷題筆記】樹、dfs、bfs、回溯、遞歸(一)

大家好 我是寸鐵👊
總結了一篇刷題關于樹、dfs、bfs、回溯、遞歸的文章?
喜歡的小伙伴可以點點關注 💝


105. 從前序與中序遍歷序列構造二叉樹

模擬分析圖

在這里插入圖片描述

代碼實現

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {return buildTree1(preorder , 0 , preorder.length , inorder , 0 , inorder.length);}public TreeNode buildTree1(int []preorder , int preLeft, int preRight , int []inorder , int inLeft , int inRight){//遞歸終止條件//中序數組中右邊界-左邊界 < 1//返回nullif(inRight - inLeft < 1){return null;}//只有一個節點//則創建該值的節點返回出去即可if(inRight - inLeft == 1){return  new TreeNode(inorder[inLeft]);}//前序遍歷中的第一個值為根節點的值int Val = preorder[preLeft];//記錄根節點的下標索引int rootIdx = 0;//在中序數組中查找到第一個值所在的下標//用于根據該下標進行數組的切割TreeNode root = new TreeNode(Val);for(int i = inLeft; i < inRight; i++){if(inorder[i] == Val){rootIdx = i;break;}}//遞歸根節點的左子樹和右子樹//注意: 編寫遞歸時要統一規范//由于上面寫的是i < inRight//這里需要不斷查找每個切分的數組的根節點進行切割。//區間是左閉右開的 要統一規范去寫//清楚是左閉右開后 編寫邏輯如下:root.left = buildTree1(preorder , preLeft + 1 , preLeft + 1 + (rootIdx - inLeft) , inorder , inLeft , rootIdx);root.right = buildTree1(preorder , preLeft+1+(rootIdx - inLeft) , preRight , inorder , rootIdx + 1 , inRight);//返回最后的根節點//每次遞歸時,向上返回該節點,接住該節點的是左孩子或者右孩子return root;}
}

106. 從中序與后序遍歷序列構造二叉樹

模擬分析圖

在這里插入圖片描述

代碼實現

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {//注:傳入的是中序和后序數組的長度//區間是左閉右開return buildTree1(inorder , 0 , inorder.length , postorder , 0 , postorder.length);}public TreeNode buildTree1(int []inorder , int inleft, int inRight , int[]postorder , int postLeft,int postRight){//對中序數組進行判斷//如果說中序數組的長度 - 起點下標 < 1 //則說明沒有元素 返回空// 0 - 0 = 0 < 1if(inRight - inleft < 1){return null;}//只有一個元素//則創建一個該元素的節點返回即可if(inRight - inleft == 1){return new TreeNode(inorder[inleft]);}//后序數組中的最后一個元素即為根起點int rootVal = postorder[postRight - 1];TreeNode root = new TreeNode(rootVal);int rootIndex = 0;//根據拿到的根節點root在中序數組中找到切割點for(int i = inleft; i < inRight; i++){if(inorder[i] == rootVal){rootIndex = i;}}//根據rootIndex在中、后序數組中劃分左右子樹//在中序中劃分root.left = buildTree1(inorder , inleft , rootIndex, postorder , postLeft , postLeft + (rootIndex - inleft));//在后序中劃分        root.right = buildTree1(inorder, rootIndex + 1, inRight , postorder , postLeft + (rootIndex - inleft) , postRight - 1);        return root;}
}

112. 路徑總和

代碼實現

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {//如果說根節點為空 則無法得到目標和 直接返回falseif(root == null) return false;//采用的是減法 看最后targetSum 減少到最后是否為0//遞歸調用 傳入根節點 此時count和為targetSum - 當前根節點的值return traversal(root , targetSum - root.val);}public boolean traversal(TreeNode cur , int count){//如果說左子樹和右子樹都為空(此為葉子節點) 并且count等于0//則說明存在路徑使得節點之和為targetSum//返回trueif(cur.left == null && cur.right == null && count == 0)return true;//否則返回falseif(cur.left == null && cur.right == null && count == 0)return false;//遞歸邏輯//遞歸左子樹if(cur.left != null){//減去當前遍歷到的節點值count -= cur.left.val;//注意:這里需要向上返回布爾值//如果往左子樹遍歷的結果為true//則向上返回trueif(traversal(cur.left , count)){return true;}//回溯 把之前減去的節點值加上//再從另一個分支去尋找是否存在路徑count += cur.left.val;}//同理,遞歸右子樹if(cur.right != null){count -= cur.right.val;if(traversal(cur.right , count)){return true;}count += cur.right.val;}return false;}
}

113. 路徑總和 II

相比較 112. 路徑總和
113. 路徑總和 II || 與下面的 129. 求根節點到葉節點數字之和
共同的邏輯都是需要遍歷一棵樹從根節點到所有葉子節點
這意味著需要一個數據結構(list)去存儲所有經過的路徑上的節點
也就意味著不需要返回值,但是由于需要遍歷所有的葉子節點
這里需要進行向上回溯,也就是怎么來的就怎么去(恢復現場)

代碼實現

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {//result隊列用于接收滿足條件的pathList<List<Integer>> result;//path用于接收每次搜索的結果//這里不用開啟全局變量//原因:path會遍歷到葉子節點會向上回溯 LinkedList<Integer> path;public List<List<Integer>> pathSum(TreeNode root, int targetSum) {result = new LinkedList<>();path = new LinkedList<>();travesal(root , targetSum);return result;}//這里由于有path接收搜索的結點//所以,這里不需要去返回值public void travesal(TreeNode root , int count){//如果說根節點為空 則直接結束if(root == null) return;//先把當前的節點值加入到path隊列中path.offer(root.val);//然后,更新當前的count 把當前添加入隊列的節點值減去count -= root.val;//接著,處理臨界條件,也就是遍歷到葉子節點對答案的判斷if(root.left == null && root.right == null && count == 0){//滿足條件則把當前遍歷的節點添加到path隊列中result.add(new LinkedList<>(path));}//向下遞歸,遍歷左子樹和右子樹//這里是直接往左子樹或者右子樹的某個方向能走的路走到底//無論是往右還是左走 走到底即可//走到底無路可走后再向上回溯 依次移除最后一個元素 再去搜索其他分支travesal(root.left , count);travesal(root.right , count);path.removeLast();}
}

debug

class Solution {List<List<Integer>> result;LinkedList <Integer> path;public List<List<Integer>> pathSum(TreeNode root, int targetSum) {result = new LinkedList<>();path = new LinkedList<>();travesal(root , targetSum);return result;}public void travesal(TreeNode root , int count){if(root == null)return;path.offer(root.val);count -= root.val;System.out.println("111111111");System.out.println(path);if(root.left == null && root.right == null && count == 0){//打印出來去看path的變化過程System.out.println("22222222");System.out.println(path);result.add(new LinkedList<>(path));}travesal(root.left , count);System.out.println("leftleftleftleftleftleft");System.out.println(path);travesal(root.right , count);System.out.println("333333333333");System.out.println(path);//依次移除掉最后一個節點,向上回溯//直至移除到最后一個根節點path.removeLast();}
}

129. 求根節點到葉節點數字之和

代碼實現

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {//path存儲dfs到的節點List<Integer>path = new LinkedList<>();//記錄最終求和的結果int res = 0;public int sumNumbers(TreeNode root) {//如果root為null 則返回0if(root == null)return 0;//如果root不為null 則把根節點添加到path中path.add(root.val);travesal(root);return res;}public void travesal(TreeNode root){//遍歷到葉子節點則對當前的path的值求和if(root.left == null && root.right == null){res += listToInt(path);}//遍歷左子樹if(root.left != null){//先添加左子樹節點的值path.add(root.left.val);//再繼續遞歸到下一層travesal(root.left);//移除掉當前隊列中的最后一個元素 向上回溯path.remove(path.size() - 1);}//遍歷右子樹if(root.right != null){path.add(root.right.val);travesal(root.right);path.remove(path.size() - 1);}}//對path中存儲的節點值進行求和public int listToInt(List<Integer> path){int sum = 0;//這里由于list是隊列 先進先出//在原來的sum基礎上乘10 再加上最后一個元素即可for(Integer s : path){sum = sum * 10 + s;}return sum;}}

總結

大邏輯其實還是最核心的三個點,一個是根節點,一個是左孩子 ,一個是右孩子
可以把遞歸函數看成是一個整體部分,整體的去對左子樹進行處理,整體
的去對右子樹進行處理,然后返回結果或者說記錄結果,不必去深究遞歸里面的細節,會讓整個的解題思路變得十分復制混亂,就是理解為遞歸函數去幫助你進行處理,最后返回一個結果或者將結果存起來就好了!


看到這里的小伙伴,恭喜你又掌握了一個技能👊
希望大家能取得勝利,堅持就是勝利💪
我是寸鐵!我們下期再見💕


往期好文💕

保姆級教程

【保姆級教程】Windows11下go-zero的etcd安裝與初步使用

【保姆級教程】Windows11安裝go-zero代碼生成工具goctl、protoc、go-zero

【Go-Zero】手把手帶你在goland中創建api文件并設置高亮


報錯解決

【Go-Zero】Error: user.api 27:9 syntax error: expected ‘:‘ | ‘IDENT‘ | ‘INT‘, got ‘(‘ 報錯解決方案及api路由注意事項

【Go-Zero】Error: only one service expected goctl一鍵轉換生成rpc服務錯誤解決方案

【Go-Zero】【error】 failed to initialize database, got error Error 1045 (28000):報錯解決方案

【Go-Zero】Error 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)報錯解決方案

【Go-Zero】type mismatch for field “Auth.AccessSecret“, expect “string“, actual “number“報錯解決方案

【Go-Zero】Error: user.api 30:2 syntax error: expected ‘)‘ | ‘KEY‘, got ‘IDENT‘報錯解決方案

【Go-Zero】Windows啟動rpc服務報錯panic:context deadline exceeded解決方案


Go面試向

【Go面試向】defer與time.sleep初探

【Go面試向】defer與return的執行順序初探

【Go面試向】Go程序的執行順序

【Go面試向】rune和byte類型的認識與使用

【Go面試向】實現map穩定的有序遍歷的方式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696138.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696138.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696138.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HarmonyOS—添加/刪除Module

Module是應用/服務的基本功能單元&#xff0c;包含了源代碼、資源文件、第三方庫及應用/服務配置文件&#xff0c;每一個Module都可以獨立進行編譯和運行。一個HarmonyOS應用/服務通常會包含一個或多個Module&#xff0c;因此&#xff0c;可以在工程中創建多個Module&#xff0…

如何利用內網穿透工具在企業微信開發者中心實現本地接口服務回調

文章目錄 1. Windows安裝Cpolar2. 創建Cpolar域名3. 創建企業微信應用4. 定義回調本地接口5. 回調和可信域名接口校驗6. 設置固定Cpolar域名7. 使用固定域名校驗 企業微信開發者在應用的開發測試階段&#xff0c;應用服務通常是部署在開發環境&#xff0c;在有數據回調的開發場…

SQL查詢每個類別價格前3的數據

SELECTproduct_id,category,price FROM (SELECTproduct_id,category,price,ROW_NUMBER() OVER (PARTITION BY category ORDER BY price) AS rankFROMyour_products_table ) AS ranked_products WHERErank < 3;DENSE_RANK() 和 ROW_NUMBER() 是窗口函數&#xff08;Window Fu…

前端知識復習

1.symbol類型 Symbol 是 ECMAScript 6 中引入的一種新的基本數據類型&#xff0c;它表示獨一無二的值。Symbol 值是通過 Symbol() 函數創建的。 Symbol 值具有以下特點&#xff1a; 獨一無二性&#xff08;唯一性&#xff09;&#xff1a;每個通過 Symbol() 函數創建的 Symb…

十三:集合

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 01、Java 集合框架概述1.1、集合框架與數組的對比及概述1.2、集合框架涉及到的API 02、Collection接口方法2.1、Collection接口中的常用方法12.2、Collection接口中…

在idea中配置Tomcat

1.在idea中點擊右上角 2.點擊Edit Configurations,點擊加號 3.向下拉找到Tomcat Server下的Local,點一下 點擊Configure 找到tomcat文件路徑,選擇apache-tomcat-8.5.63(8.5.63是我的版本號) 選擇好路徑后點ok就配置好了 總步驟:

Vue 圖片輪播第三方庫 Vue-awesome-swiper介紹及簡單例子

vue-awesome-swiper 是一個基于 Swiper 的 Vue 輪播圖組件&#xff0c;Swiper 是一個流行的移動端觸摸滑動插件。它為 Vue.js 應用提供了一套豐富的輪播組件&#xff0c;支持多種布局和功能&#xff0c;如自動播放、無限循環、觸摸滑動等。 安裝 首先&#xff…

代碼隨想錄算法訓練營第一天

● 今日學習的文章鏈接和視頻鏈接 ● 自己看到題目的第一想法 1. 704二分法&#xff1a; 方法一&#xff1a; 整個數組是 左閉右閉區間 [ ] left指針指向數組開始下標&#xff0c; right 指針指向數組最后下表nums.size()-1, mid為 (leftright) /2循環條件 left<rightnu…

打開stable diffusion webui時,提示缺少clip或clip安裝不上的解決方案(windows下的操作)

1.問題描述 打開stable diffusion webui時&#xff0c;提示缺少clip或clip安裝不上 2.解決方案 原因&#xff1a;stable diffusion webui環境中的clip其實是open_clip&#xff0c;不能用pip install clip安裝解決方法是直接到github下載 open_clip 代碼到本地&#xff0c;并…

linux環境ssh-rsa進行簽名\權限\登錄\原理(免密登錄)

linux環境ssh-rsa進行簽名權限登錄(免密登錄) SSH原理與運用什么是SSH?SSH的使用場景ssh-rsa獲取xshell環境登錄獲取ssh-rsa使用ssh-rsa登錄SHA系列SHA-1、SHA-256和RSA的區別RSA原理數論基礎RSA機制RSA數學密鑰生成公式RSA數學加密理論RSA數學簽名公式

小折疊也能成為主力機,全新小折疊旗艦華為Pocket 2正式發布

2024年2月22日&#xff0c;華為在三亞舉辦華為Pocket 2時尚盛典&#xff0c;正式發布其全新小折疊旗艦華為Pocket 2。一直以來&#xff0c;華為致力于萃取各界藝術靈感&#xff0c;不斷探尋科技美學的可能性&#xff0c;華為Pocket系列更是秉承將奢雅美學與尖端科技融為一體的理…

探索Redis是否為單線程的奧秘(文末送書)

&#x1f308;個人主頁&#xff1a;聆風吟 &#x1f525;系列專欄&#xff1a;數據結構、網絡奇遇記 &#x1f516;少年有夢不應止于心動&#xff0c;更要付諸行動。 文章目錄 &#x1f4cb;前言一. Redis中的多線程二. I/O多線程三. Redis中的多進程四. 結論五. 書籍推薦5.1 書…

高效時間管理法則

你是否天天在忙&#xff0c;是否忙的不得要領&#xff0c;認真領會時間管理的四象限工作法&#xff0c;它會讓你的工作變得高效。 目錄 一、時間管理的誤區 二、時間是如何被浪費的&#xff1f; 內部因素 外部因素 三、時間管理的5個階段 1.公雞型時間管理&#xff1a; …

第一個Qt程序中的秘密

創建第一個程序 首先我們打開Qt Creator 打開文件->New Projects... 菜單&#xff0c;創建我們的第一個Qt項目 選擇 Qt Widgets Application&#xff0c;點擊選擇...按鈕 之后&#xff0c;輸入項目名稱QtLearning&#xff0c;并選擇創建路徑&#xff0c; 在build system中選…

ConnectWise ScreenConnect 身份驗證繞過漏洞復現可RCE(CVE-2024-1709)

0x01 產品簡介 ConnectWise ScreenConnect ,是一款自托管的遠程桌面軟件應用,該款軟件允許用戶自行托管,可以在自己的服務器、個人電腦、虛擬機或虛擬專用服務器上運行。 0x02 漏洞概述 ConnectWise ScreenConnect低于23.9.8 版本的產品中,SetupWizard.aspx接口處存在身…

Android14 InputManager-焦點窗口的更新

設置焦點時需要 先設置焦點APP mFo-cusedApp是一個AppWindowToken&#xff0c;在WMS中用來表示當前處于Resume狀態的Activity。它是由AMS在開始啟動一個Activity時調用WMS的setFocusedApp&#xff08;&#xff09;函數設置的。 考慮以下應用場景&#xff0c;當用戶從Launche…

內存管理——線性內存,進程空間

低2G為進程空間 開始地址結束地址大小屬性00xFFFFF1M保留0x1000000x102FFF棧不固定位置、大小0x1030000x143FFF堆不固定位置、大小0x400000主程序文件不固定位置、大小加載dll不固定位置、大小0x7ffdd000TIB位置&#xff0c;大小編譯時固定0x7FFFE000系統與用戶共享數據塊位置…

[newstarctf2023] --RE wp

AndroGenshin: rc4加密表&#xff0c;base64換表&#xff1a; 腳本梭就行 python username b"genshinimpact" base64_table [125, 239, 101, 151, 77, 163, 163, 110, 58, 230, 186, 206, 84, 84, 189, 193, 30, 63, 104, 178, 130, 211,164, 94, 75, 16, 32, 33…

發布 rust 源碼包 (crates.io)

rust 編程語言的包 (或者 庫, library) 叫做 crate, 也就是軟件中的一個組件. 一個完整的軟件通常由多個 crate 組成, rust 編譯器 (rustc) 一次編譯一整個 crate, 不同的 crate 可以同時并行編譯. rust 官方有一個集中發布開源包的網站 crates.io. 發布在這上面的 crate 可以…

uniapp微信公眾號H5分享

如果項目文件node_modules中沒有weixin-js-sdk文件&#xff0c;則直接使用本文章提供的&#xff1b; 如果不生效&#xff0c;則在template.h5.html中引入 <script src"https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> 首先引入weixin-js-…