leetcode98.驗證二叉搜索樹:遞歸法中序遍歷的遞增性驗證之道

一、題目深度解析與BST核心性質

題目描述

驗證二叉搜索樹(BST)是算法中的經典問題,要求判斷給定的二叉樹是否滿足BST的定義:

  1. 左子樹中所有節點的值嚴格小于根節點的值
  2. 右子樹中所有節點的值嚴格大于根節點的值
  3. 左右子樹本身也必須是二叉搜索樹

BST的本質特性

  • 中序遍歷性質:BST的中序遍歷結果是一個嚴格遞增的序列。例如:
        3/ \1   5\   \2   6
    中序遍歷結果:[1, 2, 3, 5, 6](嚴格遞增)
    
  • 遞歸定義:每個節點需滿足左子樹最大值 < 當前節點值 < 右子樹最小值,但直接遞歸驗證需傳遞上下界,而通過中序遍歷的遞增性可更簡潔地驗證。

二、遞歸解法的核心實現與邏輯框架

完整遞歸代碼實現

/*** 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 {TreeNode max; // 記錄中序遍歷的前一個節點(初始為null)public boolean isValidBST(TreeNode root) {if (root == null) {return true; // 空樹是有效的BST}// 1. 遞歸驗證左子樹boolean leftValid = isValidBST(root.left);if (!leftValid) {return false; // 左子樹不合法,直接返回false}// 2. 驗證當前節點與前一個節點的關系(中序遍歷的遞增性)if (max != null && max.val >= root.val) {return false; // 當前節點值不大于前一個節點值,違反BST定義}max = root; // 更新前一個節點為當前節點(中序遍歷順序:左-中-右)// 3. 遞歸驗證右子樹boolean rightValid = isValidBST(root.right);return rightValid; // 右子樹的合法性決定最終結果}
}

核心設計解析:

  1. 全局變量max

    • 作用:記錄中序遍歷過程中訪問的前一個節點(初始為null)
    • 更新時機:在處理完左子樹后、處理右子樹前,訪問當前節點時更新
    • 核心邏輯:確保當前節點值 > 前一個節點值(中序遍歷遞增性)
  2. 遞歸順序

    • 左子樹 → 當前節點 → 右子樹(中序遍歷順序)
    • 先遞歸處理左子樹,再檢查當前節點,最后處理右子樹
    • 保證在檢查當前節點時,左子樹已完全處理,max是左子樹的最后一個節點(即當前節點的前驅)

三、核心問題解析:遞歸順序與返回值條件

1. 遞歸順序的本質:中序遍歷的遞歸實現

遞歸步驟拆解:
  1. 遞歸左子樹isValidBST(root.left)

    • 確保左子樹本身是BST,且左子樹的所有節點已按中序遍歷處理完畢
  2. 處理當前節點

    • 檢查當前節點值是否大于前一個節點值(max.val < root.val
    • 更新max為當前節點,作為后續右子樹的前驅節點
  3. 遞歸右子樹isValidBST(root.right)

    • 右子樹的所有節點值必須大于當前節點值(由中序遍歷遞增性保證)
中序遍歷映射:
遞歸順序:左子樹 → 當前節點 → 右子樹
對應中序遍歷:左子樹節點 < 當前節點 < 右子樹節點

2. 返回值條件的邏輯閉環

條件判斷鏈:
  • 左子樹不合法:直接返回false,無需繼續檢查
  • 當前節點不滿足遞增性:返回false,右子樹無需檢查
  • 右子樹不合法:返回false,整個樹不合法
代碼中的短路效應:
if (!leftValid) return false; // 左子樹失敗則整體失敗
if (max != null && max.val >= root.val) return false; // 當前節點失敗則整體失敗
return rightValid; // 右子樹決定最終結果

四、遞歸流程深度模擬:以無效BST為例

示例無效BST結構:

    5/ \4   6/ \3   7

問題:左子節點4 >= 根節點5?不,實際問題在右子樹3 < 根節點6

遞歸驗證過程:

  1. 處理根節點5
    • 遞歸左子樹4(葉子節點,返回true)
    • 檢查max=null,更新max=4
    • 遞歸右子樹6:
      • 遞歸左子樹3(葉子節點,返回true)
      • 檢查max=4 < 3?不,4 >= 3,返回false
    • 根節點5的右子樹驗證失敗,整體返回false

關鍵失敗點:

  • 右子樹的左節點3值為3,前一個節點是根節點5的左子樹節點4,4 >= 3,違反遞增性

五、算法復雜度分析

1. 時間復雜度

  • O(n):每個節點僅訪問一次,n為樹的節點數
  • 遞歸過程中每個節點執行常數級操作,總時間線性于節點數

2. 空間復雜度

  • O(h):h為樹的高度(遞歸棧深度)
    • 平衡BST:h=logn,空間復雜度O(logn)
    • 最壞情況(退化為鏈表):h=n,空間復雜度O(n)

3. 與迭代法對比

方法優勢劣勢
遞歸法代碼簡潔,中序遍歷自然遞歸實現深樹可能導致棧溢出
迭代法避免棧溢出,空間更可控棧操作邏輯較復雜

六、核心技術點總結:遞歸驗證的三大關鍵

1. 中序遍歷的遞歸映射

  • 順序保證:遞歸順序天然符合中序遍歷的左-中-右順序
  • 狀態傳遞:通過全局變量max傳遞中序遍歷的前驅節點,避免顯式傳遞上下界

2. 遞增性的核心判斷

  • 單一條件:無需檢查復雜的上下界,只需保證當前節點 > 前驅節點
  • 數學等價:中序遍歷遞增性等價于BST的嚴格定義,簡化判斷邏輯

3. 遞歸終止條件的設計

  • 空樹處理:直接返回true,作為遞歸終止的安全邊界
  • 葉子節點:左右子樹為空時,僅需檢查自身與前驅節點的關系

七、常見誤區與優化建議

1. 錯誤理解BST定義

  • 誤區:認為只需當前節點左右子節點滿足條件即可
    // 錯誤做法:僅比較左右子節點
    if (root.left != null && root.left.val >= root.val) return false;
    if (root.right != null && root.right.val <= root.val) return false;
    
  • 正確邏輯:需保證左子樹所有節點 < 當前節點,而非僅左子節點

2. 忽略全局變量的作用

  • 誤區:未使用前驅節點記錄,導致無法驗證跨層節點關系
  • 正確設計max記錄中序前驅,確保整個序列遞增

3. 優化建議:顯式傳遞上下界(遞歸法變種)

public boolean isValidBST(TreeNode root) {return validate(root, null, null);
}private boolean validate(TreeNode node, Integer lower, Integer upper) {if (node == null) return true;int val = node.val;// 當前節點需滿足 lower < val < upperif (lower != null && val <= lower) return false;if (upper != null && val >= upper) return false;// 左子樹最大值 < val,右子樹最小值 > valreturn validate(node.left, lower, val) && validate(node.right, val, upper);
}
  • 優勢:顯式傳遞上下界,邏輯更嚴謹,避免依賴全局變量
  • 原理:每個節點的合法值范圍由父節點決定,左子樹值 < 當前節點值,右子樹值 > 當前節點值

八、總結:遞歸法驗證BST的本質是中序遞增性的遞歸實現

本算法通過遞歸實現中序遍歷,利用BST的中序遞增性簡化驗證邏輯,核心在于:

  1. 遞歸順序的選擇:左-中-右的遞歸順序天然對應中序遍歷,確保前驅節點的正確性
  2. 狀態的隱式傳遞:通過全局變量max記錄前驅節點,避免復雜的參數傳遞
  3. 條件的短路效應:左子樹或當前節點驗證失敗時立即返回,提高效率

理解這種遞歸解法的關鍵是將BST的復雜定義轉化為中序遍歷的簡單遞增性判斷。遞歸法的簡潔性使其成為驗證BST的經典解法,尤其適合樹深度較小的場景。在實際工程中,需根據樹的規模選擇遞歸或迭代實現,平衡代碼簡潔性與穩定性。

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

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

相關文章

MathQ-Verify:數學問題驗證的五步流水線,為大模型推理筑牢數據基石

MathQ-Verify&#xff1a;數學問題驗證的五步流水線&#xff0c;為大模型推理筑牢數據基石 大語言模型在數學推理領域進展顯著&#xff0c;但現有研究多聚焦于生成正確推理路徑和答案&#xff0c;卻忽視了數學問題本身的有效性。MathQ-Verify&#xff0c;通過五階段流水線嚴格…

八股戰神-JVM知識速查

1.JVM組成 JVM由那些部分組成&#xff0c;運行流程是什么&#xff1f; JVM是Java程序的運行環境 組成部分&#xff1a; 類加載器&#xff1a;加載字節碼文件到內存 運行時數據區&#xff1a;包括方法區&#xff0c;堆&#xff0c;棧&#xff0c;程序計數器&#xff0c;本地…

Maven:在原了解基礎上對pom.xml文件進行詳細解讀

一、pom.xml文件 就像項目管理軟件 Make 的 MakeFile、Ant 的 build.xml 一樣&#xff0c;Maven 項目的核心是 pom.xml。POM( Project Object Model&#xff0c;項目對象模型 ) 定義了項目的基本信息&#xff0c;用于描述項目如何構建&#xff0c;聲明項目依賴&#xff0c;等等…

Spring Cloud項目登錄認證從JWT切換到Redis + UUID Token方案

背景介紹 在傳統的Spring Boot項目中&#xff0c;用戶登錄認證常見的方案是使用JWT&#xff08;JSON Web Token&#xff09;來實現無狀態的身份驗證。JWT憑借自包含用戶信息、方便前后端分離、性能較好等優勢被廣泛采用。 然而&#xff0c;在實際項目中&#xff0c;JWT也有一…

MongoDB 快速整合 SpringBoot 示例

1.添加依賴<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spr…

Flyweight(享元)設計模式 軟考 享元 和 代理屬于結構型設計模式

1.目的&#xff1a;運用共享技術有效地支持大量細粒度的對象 Flyweight&#xff08;享元&#xff09;設計模式 是一種結構型設計模式&#xff0c;它的核心目的是通過共享對象來減少內存消耗&#xff0c;特別是在需要大量相似對象的場景中。Flyweight 模式通過將對象的共享細節與…

002大模型-提示詞工程,少樣本提示,角色扮演,思維鏈

一、提示詞工程 二、少樣本提示 三、角色扮演 四、思維鏈

華為OD機試真題——傳遞悄悄話(二叉樹最長路徑問題)(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳實現

2025 A卷 200分 題型 本專欄內全部題目均提供Java、python、JavaScript、C、C++、GO六種語言的最佳實現方式; 并且每種語言均涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、3個測試用例以及綜合分析; 本文收錄于專欄:《2025華為OD真題目錄+全流程解析+備考攻略+經驗分…

「讀書報告」Spark實時大數據分析

這本書是清華大學出版社2018年出版的&#xff0c;我是2020年讀的&#xff0c;說真的的&#xff0c;不怎么喜歡這本書&#xff0c;所以作者我都不想提。有的人可能會奇怪&#xff0c;ailx10&#xff0c;你一個搞網絡安全的&#xff0c;怎么會去讀大數據相關的書&#xff0c;哎&a…

2025 河北ICPC( D. 金泰園(二分)-- C.年少的誓約(公式轉化))

文章目錄 2025 河北ICPCD. 金泰園&#xff08;二分&#xff09;C.年少的誓約(公式轉化)總結 2025 河北ICPC 題目鏈接&#xff1a; Attachments - The 9th Hebei Collegiate Programming Contest - Codeforces sdccpc20250522 - Virtual Judge 賽時&#xff1a;5道 D. 金泰…

QT學習一

對于選擇qmake還是cmake&#xff0c;現在寫的暫時先用qmake 1.命名規范和快捷鍵 2.按鈕控件常用API //創建第一個按鈕QPushButton * btn new QPushButton;//讓btn對象 依賴在mywidget窗口中btn->setParent(this);//顯示文本btn->setText("第一個按鈕");//創建…

【Elasticsearch】給所索引創建多個別名

Elasticsearch 是可以給索引創建多個別名的。 為什么可以創建多個別名 1. 靈活性 - 別名可以為索引提供一個更易于理解的名稱&#xff0c;方便用戶根據不同的業務場景或用途來引用同一個索引。例如&#xff0c;一個索引可能同時服務于多個不同的應用程序或服務&#xff0c;通…

使用 OpenCV 實現哈哈鏡效果

在計算機視覺和圖像處理領域&#xff0c;OpenCV 提供了非常強大的圖像幾何變換能力&#xff0c;不僅可以用于糾正圖像&#xff0c;還能制造各種“有趣”的視覺效果。今天&#xff0c;我們就來實現一個經典的“哈哈鏡”效果&#xff0c;讓圖像像在游樂園里一樣被拉伸、壓縮、扭曲…

AI|Java開發 IntelliJ IDEA中接入本地部署的deepseek方法

目錄 連接本地部署的deepseek&#xff1a; IntelliJ IDEA中使用deepseek等AI&#xff1a; 用法一&#xff1a;讓AI寫代碼 用法二&#xff1a;選中這段代碼&#xff0c;右鍵&#xff0c;可以讓其解釋這段代碼的含義。這時顯示的解釋是英文的。 連接本地部署的deepseek&#…

如何使用兩塊硬盤作為 Ubuntu24 的系統盤,實現壞掉一塊不影響系統運行。

最近我想使用Ubuntu組一個NAS系統&#xff0c;想實現系統盤冗余&#xff0c;各位大佬可以給點建議嗎。 Deep Seek 為了實現兩塊硬盤作為 Ubuntu 24 系統盤的冗余配置&#xff08;RAID 1&#xff09;&#xff0c;確保一塊硬盤損壞時系統仍可運行&#xff0c;以下是詳細步驟&am…

【2025最新】虛擬機安裝macos,VMware在Windows11上安裝macOS 15完整圖文教程 - 新手也能輕松上手

引言 想體驗蘋果系統但不想買Mac電腦&#xff1f;別擔心&#xff01;本教程將手把手教你如何在Windows11環境下&#xff0c;通過VMware虛擬機安裝macOS Sequoia15系統。即使你是零基礎小白&#xff0c;按照這個步驟操作&#xff0c;也能輕松搞定&#xff01; 準備工作 在開始…

論文閱讀筆記——Emerging Properties in Unified Multimodal Pretraining

BAGEL 論文 商業閉源系統與學術/開源模型的差距很大&#xff0c;BAGEL 旨在通過開源統一架構大規模交錯數據主要解決&#xff1a; 架構割裂&#xff1a;理解/生成分屬兩條網絡&#xff0c;信息被壓縮在少量條件 token 中&#xff0c;長上下文推理受限。數據貧乏&#xff1a;主…

Go 語言基礎1 Slice,map,string

更多個人筆記見&#xff1a; github個人筆記倉庫 gitee 個人筆記倉庫 個人學習&#xff0c;學習過程中還會不斷補充&#xff5e; &#xff08;后續會更新在github上&#xff09; 文章目錄 stirng 字符串區分 rune&#xff0c;byte&#xff0c;string字符串操作strings 庫相關 f…

C# AI(Trae工具+claude3.5-sonnet) 寫前后端

這是一個AI 寫的前后端分離項目,通過AI編程&#xff0c;開發電商管理系統&#xff08;登陸、注冊&#xff09; 使用的AI工具為 Trae工具(字節國際版)claude3.5-sonnet(目前代碼最強模型) 前端為 vue3Bootstrap 后端為 C# net5.0(因為我電腦里面已經安裝了這個新版更好) do…

10G/25G PCS only mode for CoaXPress Over Fiber

背景 在CoaXPress Over Fiber的需求中, 需要利用XGMII的PCS 實現25G 數據速率的穩定傳輸&#xff0c;也就是不需要其MAC層&#xff0c;只保留PMA PCS層&#xff0c;借用其物理端口 線纜&#xff0c;實現其它協議的數據傳輸。 25G PCS 25GMII 的 TX/RX 時鐘頻率在 DDR&#xff…