LeetCode513:找樹最左下角的值(bfs+dfs)

文章目錄

  • 一、 題目描述
  • 解法一:層序遍歷 (BFS) - 最直觀的解法
    • 核心思路
    • 代碼實現
    • 優缺點分析
  • 解法二:遞歸 (DFS) - 更深度的思考
    • 核心思路
    • 代碼實現
    • 優缺點分析
  • 四、 總結與對比

LeetCode 513 - 尋找樹的最后一行的最左側的值,【難度:中等;通過率:73.8%】,這道題是檢驗對兩種核心遍歷策略——廣度優先搜索 (BFS) 和深度優先搜索 (DFS) 理解與運用的絕佳試金石

一、 題目描述

給定一個二叉樹的根節點 root,請找出該二叉樹的 最底層 最左邊 節點的值

假設二叉樹中至少有一個節點

示例:

示例 1:
示例 1

輸入: root = [2,1,3]
輸出: 1

示例 2:
示例 2

輸入: root = [1,2,3,4,null,5,6,null,null,7]
輸出: 7

解法一:層序遍歷 (BFS) - 最直觀的解法

既然問題涉及到“層”和“行”,那么廣度優先搜索 (BFS) 無疑是最自然、最直觀的解題思路。我們只需要逐層遍歷,并想辦法記錄下每一層的第一個節點即可

核心思路

  1. 使用隊列進行標準的層序遍歷
  2. while 循環中,我們知道每一次循環都將處理新的一層
  3. 在開始處理這一層的所有節點之前,隊列的頭部元素 (queue.peek()) 正是這一層的最左側節點
  4. 我們用一個變量 resultNode 來不斷更新這個“每層的最左側節點”。當整個 while 循環結束時,resultNode 自然就指向了最后一層的最左側節點

代碼實現

class Solution {public int findBottomLeftValue(TreeNode root) {Queue<TreeNode> queue = new LinkedList<>(); // 也可自行選擇其他高效實現queue.add(root);TreeNode resultNode = null; // 用于記錄最終結果節點while (!queue.isEmpty()) {// 在處理本層節點前,隊列的頭部就是本層的最左側節點// 用 resultNode 把它“暫存”起來resultNode = queue.peek();int levelSize = queue.size(); // 獲取初始當前層的節點數量// 遍歷并處理當前層的所有節點for (int i = 0; i < levelSize; i++) {TreeNode node = queue.poll();// 將下一層的節點(從左到右)加入隊列if (node.left != null) {queue.add(node.left);}if (node.right != null) {queue.add(node.right);}}}// 循環結束后,resultNode 指向的就是最后一層的最左側節點return resultNode.val;}
}

優缺點分析

  • 優點:思路與問題描述高度契合,代碼邏輯清晰,易于理解
  • 缺點:需要使用隊列,空間復雜度為 O(W),其中 W 是樹的最大寬度。對于一個茂盛的樹,空間開銷較大

解法二:遞歸 (DFS) - 更深度的思考

我們也可以用深度優先搜索(DFS)來解決這個問題。這里的核心思想是:如果我們能記錄下每個節點的深度,那么我們只需要找到擁有最大深度的、并且最靠左的那個節點即可

核心思路

  1. 定義兩個全局變量:maxDepth 記錄遍歷過程中遇到的最大深度,resultVal 記錄在最大深度下最左側節點的值
  2. 進行一次深度優先搜索(遞歸)。為了確保找到的是“最左側”的節點,我們采用先序遍歷的順序(根-左-右)
  3. 在遍歷每個節點時,我們比較當前節點的深度 currentDepth 和已知的最大深度 maxDepth
  4. 如果 currentDepth > maxDepth,這意味著我們第一次到達了一個更深的層次。由于我們是先遍歷左子樹,所以當前這個節點一定是這個新深度下的最左側節點。此時,我們更新 maxDepthresultVal
  5. 如果 currentDepth <= maxDepth,我們不做任何操作,因為我們已經在這個深度或更深的深度找到了最左側的節點

代碼實現

class Solution {int maxDepth = -1; // 記錄已發現的最大深度int resultVal = 0;   // 記錄最大深度下最左側節點的值public int findBottomLeftValue(TreeNode root) {// 從根節點開始 DFS,初始深度為 0dfs(root, 0);return resultVal;}/*** dfs* @param node  當前節點* @param depth 當前節點的深度*/private void dfs(TreeNode node, int depth) {if (node == null) {return;}// 核心邏輯:判斷是否發現了新的更深層// 因為我們是先序遍歷(先左后右),所以第一次到達一個新深度時,// 當前節點必然是該深度的最左側節點if (depth > maxDepth) {maxDepth = depth; // 更新最大深度resultVal = node.val; // 更新結果值}// 搜索左子樹dfs(node.left, depth + 1);// 搜索右子樹dfs(node.right, depth + 1);}
}

優缺點分析

  • 優點:空間復雜度僅為遞歸棧的深度 O(H),對于窄而深的樹,空間效率優于 BFS
  • 缺點:思路相對 BFS 來說不那么直觀,需要正確處理深度和值的更新邏輯

四、 總結與對比

解法一 (層序遍歷 / BFS)解法二 (遞歸 / DFS)
核心思路逐層遍歷,不斷用每層的第一個節點覆蓋結果,直到最后一層深度優先,利用遍歷順序和深度記錄,找到第一個到達最大深度的節點
數據結構隊列 (Queue)遞歸棧
時間復雜度O(N)O(N)
空間復雜度O(W) (樹的最大寬度)O(H) (樹的最大高度)
代碼可讀性高,與問題描述匹配中等,需要理解深度更新的邏輯
適用場景解決所有與“層”相關的問題,通用性強空間效率可能更高,尤其是在處理細長的樹時

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

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

相關文章

把“評論”菜單從WordPress后臺移除的3種方法

在WordPress后臺移除“評論”菜單&#xff0c;可以通過以下幾種方法實現。以下是詳細步驟&#xff1a; 方法1&#xff1a;通過代碼移除(推薦) 將以下代碼添加到主題的functions.php文件中(或使用CodeSnippets插件)&#xff1a; // 移除后臺左側菜單的“評論” add_action(ad…

大語言模型 LLM 通過 Excel 知識庫 增強日志分析,根因分析能力的技術方案(4):只要過一遍LLM的簡約版本

文章大綱 只要過一遍LLM的簡約版本 1 設計原理(一句話) 2 極簡數據流 3 最小依賴實現(本地 SQLite + OpenAI 兼容端點) 3.1 一次性準備:Excel → SQLite 3.2 關鍵詞提取 + 查表(正則 / SQL) 3.3 單次 LLM 調用 4 運行結果示例 5 性能 & Token 對比 6 可擴展點 7 參考…

(轉)mybatis和hibernate的 緩存區別?

MyBatis 和 Hibernate 都是流行的 Java 持久化框架&#xff0c;它們都提供了自己的緩存機制來優化數據庫操作&#xff0c;減少數據庫的訪問次數&#xff0c;提高應用程序的性能。盡管兩者都支持緩存&#xff0c;但是它們的緩存實現方式和配置有所不同。1. 緩存機制的基本區別My…

【linux內核系列】:萬字詳解進程間通信:消息隊列

&#x1f525; 本文專欄&#xff1a;Linux &#x1f338;作者主頁&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客勵志語錄&#xff1a; 你討厭的現在&#xff0c;是未來的你拼命想回去修正的戰場。 ★★★ 本文前置知識&#xff1a; 匿名管道 命名管道 共享內存 前…

React 19 革命性升級:編譯器自動優化,告別手動性能調優時代

概述 React 19 是 React 框架的一個重要里程碑版本&#xff0c;帶來了眾多突破性的改進和新特性。本文檔將詳細介紹 React 19 的主要變化&#xff0c;幫助開發者了解并遷移到新版本。 &#x1f680; 主要新特性 React Compiler (編譯器) React 19 引入了全新的 React Compi…

UE5的渲染Debug技巧

ShaderPrint UE5相對UE4使用的ComputeShader(GPU Driven)的地方多很多。因為UE5為了方便查看ComputeShader的某些值&#xff0c;開發了“ShaderPrint”&#xff0c;方便直接在Shader 打印信息到屏幕&#xff0c;而不用采用CPUReadback在print的方式。 比如r.nanite.ShowStats…

【2025/08/03】GitHub 今日熱門項目

GitHub 今日熱門項目 &#x1f680; 每日精選優質開源項目 | 發現優質開源項目&#xff0c;跟上技術發展趨勢 &#x1f4cb; 報告概覽 &#x1f4ca; 統計項&#x1f4c8; 數值&#x1f4dd; 說明&#x1f4c5; 報告日期2025-08-03 (周日)GitHub Trending 每日快照&#x1f55…

Android系統模塊編譯調試與Ninja使用指南

模塊編譯調試方法 (此處舉例framework、installd、SystemUI等模塊的編譯調試&#xff0c;其他類似) 1. Framework模塊編譯 Android系統代碼的framework目錄內&#xff0c;一共有3個模塊單獨編譯&#xff1a;framework、services、framework-res.apk。 注意&#xff1a;偶爾會有…

【硬件-筆試面試題】硬件/電子工程師,筆試面試題-51,(知識點:stm32,GPIO基礎知識)

目錄 1、題目 2、解答 3、相關知識點 一、GPIO 基本結構與特性 1. GPIO 硬件結構 2. 主要特性 二、GPIO 工作模式 1. 輸入模式 2. 輸出模式 3. 復用功能模式 4. 特殊模式 三、GPIO 配置步驟&#xff08;以 STM32Cube HAL 庫為例&#xff09; 1. 初始化 GPIO 時鐘 …

小智服務器Java安裝編譯(xinnan-tech)版

github&#xff1a;https://github.com/xinnan-tech/xiaozhi-esp32-server 一、JDK 1、JDK21下載&#xff1a; https://www.oracle.com/cn/java/technologies/downloads/#jdk21-windows RPM安裝&#xff1a; rpm -ivh jdk-21_linux-x64_bin.rpm 2、IDEA設置JDK File → P…

智能平臺的感知進化:AI × 視頻通感在群體終端協同中的應用探索

?? 引言&#xff1a;從單兵到集群&#xff0c;未來智能平臺的協同演進 從傳統的單兵執行任務到如今的“群體智能平臺編組”&#xff0c;現代感知系統正經歷一場由 AI、機器人與智能計算平臺驅動的深度變革。過去&#xff0c;履帶式無人平臺在平坦地形中承擔支援任務&#xf…

基于定制開發開源AI智能名片S2B2C商城小程序的B站私域流量引流策略研究

摘要&#xff1a;隨著移動互聯網進入存量競爭階段&#xff0c;私域流量運營成為企業數字化轉型的核心戰略。B站作為中國最大的Z世代文化社區&#xff0c;其3.41億月活躍用戶中Z世代占比達58%&#xff0c;且25歲以上用戶增速顯著&#xff0c;用戶日均使用時長超108分鐘&#xff…

Spring+K8s+AI實戰:3全棧開發指南

Spring、K8s、人工智能、Docker及Windows實例 以下是與Spring、K8s、人工智能、Docker及Windows實例相關的實用示例,涵蓋開發、部署和集成場景: Spring Boot微服務開發 示例1:REST API構建 使用Spring Boot創建帶Swagger文檔的RESTful服務,集成JPA和Hibernate進行數據庫…

C++ 生成動態庫.dll 及 C++調用DLL,C++ 生成靜態庫.lib及 C++調用lib

文章目錄1 C 動態庫.dll生成 及 調用1.1 生成C 動態庫dll1.1.1 創建項目MyDLL1.1.2 編寫.h 和 .cpp文件1.1.3 設置 及 生成 DLL1.2 調用 C 動態庫dll1.2.1 創建C 空項目DLLtest1.2.2 動態庫配置 及代碼調用測試2 C 靜態庫.lib 生成 及 調用3 C 生成靜態庫.lib及調用 &#xff0…

信創應用服務器TongWeb安裝教程、前后端分離應用部署全流程

TongWeb 簡介TongWeb 是東方通&#xff08;TongTech&#xff09;開發的國產Java應用服務器&#xff08;中間件&#xff09;&#xff0c;類似于國外的 WebLogic、WebSphere 和開源的 Tomcat、Jetty&#xff0c;主要用于企業級Java應用&#xff08;如J2EE&#xff09;的部署和運行…

Rust 同步方式訪問 REST API 的完整指南

Rust 同步方式訪問 REST API 的完整指南 在 Rust 中不使用異步機制訪問 REST API 是完全可行的&#xff0c;特別適合簡單應用、腳本或不需要高并發的場景。以下是完整的同步實現方案&#xff1a; &#x1f4e6; 依賴選擇 推薦庫&#xff1a; [dependencies] reqwest { version…

32.【.NET8 實戰--孢子記賬--從單體到微服務--轉向微服務】--單體轉微服務--財務服務--賬本與預算

在我們的孢子記賬應用中&#xff0c;賬本是用于記錄每一筆收支流水的核心模塊。通過賬本&#xff0c;我們可以清晰地追蹤資金的流入與流出&#xff0c;進行數據統計和分析&#xff0c;為后續的報表生成和決策支持提供基礎數據。預算模塊則是用于設置和管理預算的功能&#xff0…

模型預估打分對運籌跟蹤的影響

在uplift建模中&#xff0c;模型離線指標(QINI、AUUC)提升并不意味著在線A/B實驗的收益&#xff0c;因為在線運籌還需要λ\lambdaλ約束。如果模型打分不滿足單調增且roi邊際遞減&#xff0c;那么λ\lambdaλ運籌求解會非常不穩定&#xff0c;導致線上發券偏高&#xff0c;毛利…

音視頻學習(四十六):聲音的三要素

聲音是人類感知世界的重要途徑之一。在自然界中&#xff0c;聲波本質上是介質中傳播的機械振動&#xff0c;而人類對聲音的主觀感受主要通過三種屬性來認知和描述&#xff0c;即音調&#xff08;音高&#xff09;、響度&#xff08;強弱&#xff09;、音色&#xff08;音質&…

spring batch處理數據模板(Reader-Processor-Writer模式)

步驟監聽器 Component public class StepListener implements StepExecutionListener {private StepExecution stepExecution;public StepExecution getStepExecution() {return this.stepExecution;}Overridepublic void beforeStep(StepExecution stepExecution) {this.stepE…