【LeetCode熱題100道筆記】驗證二叉搜索樹

題目描述

給你一個二叉樹的根節點 root ,判斷其是否是一個有效的二叉搜索樹。

有效 二叉搜索樹定義如下:

節點的左子樹只包含 嚴格小于 當前節點的數。
節點的右子樹只包含 嚴格大于 當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜索樹。

示例 1:
在這里插入圖片描述
輸入:root = [2,1,3]
輸出:true

示例 2:
在這里插入圖片描述
輸入:root = [5,1,4,null,null,3,6]
輸出:false
解釋:根節點的值是 5 ,但是右子節點的值是 4 。

提示:
樹中節點數目范圍在[1,104][1, 10^4][1,104]
?231<=Node.val<=231?1-2^31 <= Node.val <= 2^31 - 1?231<=Node.val<=231?1

思考一:前序遍歷(遞歸檢測值范圍)

二叉搜索樹的根節點的值大于所有左子樹的節點,小于所有右子樹的節點。寫遞歸函數時很容易把節點值的范圍搞錯,如下圖不是二叉搜索樹:
在這里插入圖片描述
節點41 小于祖先節點42,不滿足二叉搜索樹根節點右子樹所有節點大于根節點值條件。
因此要定義一個遞歸函數,設置上下限參數,檢測左子樹時才更新上限值,檢測右子樹時才更新下限值。
核心是為每個節點設定合法值區間:根節點的合法區間為 (-∞, +∞),左子節點的區間上限更新為父節點值(需嚴格小于父節點),右子節點的區間下限更新為父節點值(需嚴格大于父節點),遞歸驗證所有節點是否在合法區間內。

算法過程

  1. 初始化遞歸:調用輔助函數 check,傳入根節點及初始區間 (-Infinity, Infinity)(根節點無上下限約束)。
  2. 遞歸終止條件:若當前節點為 null(空樹/空子樹),符合BST規則,返回 true
  3. 節點值合法性檢測
    • 若當前節點值 <= 區間下限>= 區間上限(違反“左小右大”規則),返回 false
  4. 遞歸驗證子樹
    • 驗證左子樹:左子樹的合法區間為 (原下限, 當前節點值)(左子樹需嚴格小于當前節點);
    • 驗證右子樹:右子樹的合法區間為 (當前節點值, 原上限)(右子樹需嚴格大于當前節點);
    • 只有左右子樹均驗證通過,才返回 true
  5. 返回結果:遞歸回溯后,返回最終驗證結果。

時空復雜度

  • 時間復雜度:O(n),n為二叉樹節點總數。
    原因:每個節點僅被驗證1次,遞歸操作無重復遍歷,總操作次數與節點數線性相關。
  • 空間復雜度:O(h),h為二叉樹高度。
    原因:遞歸調用棧深度取決于樹高,平衡樹h=O(log n),鏈狀樹h=O(n)。

代碼(前序遍歷版)

/*** Definition for a binary tree node.* function TreeNode(val, left, right) {*     this.val = (val===undefined ? 0 : val)*     this.left = (left===undefined ? null : left)*     this.right = (right===undefined ? null : right)* }*/
/*** @param {TreeNode} root* @return {boolean}*/
var isValidBST = function(root) {// 初始區間:根節點無上下限,用正負無窮表示return check(root, -Infinity, Infinity);
};// 輔助函數:驗證節點是否在 [low, high) 區間內(左閉右開,保證嚴格大小)
function check(node, low, high) {// 空節點符合BST規則if (!node) return true;// 節點值超出合法區間,不是BSTif (node.val <= low || node.val >= high) {return false;}// 左子樹區間更新為 [low, node.val),右子樹更新為 [node.val, high)return check(node.left, low, node.val) && check(node.right, node.val, high);
}

思考二:中序遍歷(驗證序列嚴格遞增)

核心是利用BST的中序遍歷特性:BST的中序遍歷結果是嚴格遞增的序列(左→根→右,值依次增大)。通過中序遍歷收集節點值,再檢查序列是否嚴格遞增,即可驗證是否為有效BST。

算法過程

  1. 中序遍歷收集節點值
    • 初始化空數組 arr,用于存儲中序遍歷的節點值;
    • 遞歸執行中序遍歷:先遍歷左子樹,再將當前節點值加入 arr,最后遍歷右子樹(左→根→右)。
  2. 驗證序列嚴格遞增
    • 遍歷數組 arr,若存在任意 i 滿足 arr[i] >= arr[i+1](非嚴格遞增),返回 false
    • 若所有相鄰元素均滿足 arr[i] < arr[i+1],返回 true
  3. 返回結果:返回序列驗證結果。

時空復雜度

  • 時間復雜度:O(n),n為二叉樹節點總數。
    原因:中序遍歷收集節點值需O(n),遍歷數組驗證需O(n),總時間為O(n)。
  • 空間復雜度:O(n)(含存儲數組)。
    原因:數組 arr 需存儲所有節點值(O(n)),遞歸調用棧需O(h),總空間由數組主導,為O(n)。
    (優化:可不用數組,用變量記錄前一個節點值,空間復雜度降至O(h),見下方補充)

代碼(中序遍歷版,基礎版)

/*** Definition for a binary tree node.* function TreeNode(val, left, right) {*     this.val = (val===undefined ? 0 : val)*     this.left = (left===undefined ? null : left)*     this.right = (right===undefined ? null : right)* }*/
/*** @param {TreeNode} root* @return {boolean}*/
var isValidBST = function(root) {const arr = [];// 中序遍歷收集節點值inOrder(root, arr);// 驗證序列是否嚴格遞增for (let i = 0; i < arr.length - 1; i++) {if (arr[i] >= arr[i + 1]) return false;}    return true;
};// 中序遍歷:左→根→右
function inOrder(node, arr) {if (!node) return;inOrder(node.left, arr);arr.push(node.val);inOrder(node.right, arr);
}
中序遍歷優化版(無數組,O(h)空間)
var isValidBST = function(root) {let prev = -Infinity; // 記錄前一個節點值,初始為負無窮let isValid = true;   // 標記是否為有效BSTfunction inOrder(node) {if (!node || !isValid) return; // 提前終止(已判定無效)inOrder(node.left);            // 左// 驗證當前節點值是否大于前一個節點值if (node.val <= prev) {isValid = false;return;}prev = node.val;               // 更新前一個節點值(根)inOrder(node.right);           // 右}inOrder(root);return isValid;
};

兩種方法對比

方法核心邏輯時間復雜度空間復雜度(基礎版)優勢
前序遍歷(值范圍)遞歸驗證節點合法區間O(n)O(h)無額外存儲,空間更優
中序遍歷(有序性)驗證中序序列嚴格遞增O(n)O(n)(數組)邏輯直觀,易理解
中序遍歷(優化版)實時對比前節點值O(n)O(h)兼顧直觀與空間效率

適用場景

  • 若追求空間效率,優先選擇“前序遍歷(值范圍)”或“中序遍歷優化版”;
  • 若追求代碼簡潔直觀,可選擇“中序遍歷(數組版)”(節點數較少時無明顯性能問題)。

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

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

相關文章

Apache Tomcat 教程:從入門到精通(含目錄結構與版本詳解)

??????1. 背景?? Apache Tomcat 是一個開源的 ??Java Servlet 容器??&#xff0c;由 ??Apache 軟件基金會&#xff08;ASF&#xff09;?? 開發和維護&#xff0c;最初由 ??Sun Microsystems?? 的軟件架構師 ??James Duncan Davidson?? 設計&#xff0…

設計模式從入門到精通之(六)策略模式

策略模式&#xff1a;讓算法靈活切換的秘密武器在日常開發中&#xff0c;算法的選擇常常是程序設計的核心&#xff0c;比如支付方式的選擇、排序邏輯的切換、促銷活動的動態調整等。當需求變化時&#xff0c;我們需要在多個算法之間切換&#xff0c;但又不希望修改已有代碼。如…

安裝MATLAB205軟件記錄

安裝MATLAB2025 一臺電腦可以安裝多個版本的MATLAB; 下載資源 微信公眾平臺-MATLAB R2025a v25.1下載及安裝教程 安裝步驟 解壓, 壓縮文件大小為13.8GB 裝載 選中setup.exe右鍵單擊以管理員身份運行 我有文件安裝密鑰 接受許可條款 復制粘貼密鑰 63733-59078-50866-02827-…

MySQL 基礎架構(一):SQL語句的執行之旅

MySQL系列文章 MySQL 基礎架構&#xff08;一&#xff09;&#xff1a;SQL語句的執行之旅 你是否好奇過&#xff0c;一條看似簡單的SQL查詢語句&#xff0c;在MySQL內部究竟經歷了怎樣的"奇幻之旅"&#xff1f;從連接建立到結果返回&#xff0c;MySQL是如何層層處理、…

Spring Boot 使用 Druid 連接池極致優化

在 Spring Boot 中使用 Druid 連接池進行極致優化&#xff0c;需要從核心參數調優、監控體系搭建、安全增強、連接管理及性能適配等多個維度綜合考慮。以下是分階段的詳細優化策略&#xff1a;一、基礎環境準備確保使用最新穩定版 Druid&#xff08;截至 2024 年推薦 1.2.38&am…

【Big Data】Apache Kafka 分布式流處理平臺的實時處理實踐與洞察

目錄 一、Apache Kafka是什么 二、Kafka的誕生背景 三、Kafka的架構設計 四、Kafka解決的技術問題 五、Kafka的關鍵特性 六、Kafka與其他消息隊列系統的對比 七、Kafka的工作原理 八、Kafka的部署與使用方法 1. 集群部署 2. 生產者與消費者配置 3. 安全配置 4. 監控…

23種設計模式——裝飾器模式(Decorator Pattern)詳解

?作者簡介&#xff1a;大家好&#xff0c;我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式&#xff0c;持續分享Java技術內容。 &#x1f34e;個人主頁&#xff1a;Meteors.的博客 &#x1f49e;當前專欄&#xff1a;設計模式 ?特色專欄&#xff1a;知識分享 &#x…

《sklearn機器學習——聚類性能指標》Davies-Bouldin Index (戴維斯-博爾丁指數)

Davies-Bouldin Index (戴維斯-博爾丁指數)簡介 概念與定義 Davies-Bouldin Index是由David L. Davies和Donald W. Bouldin于1979年提出的一種用于評估聚類算法效果的內部指標。它通過計算每個簇內數據點之間的相似性和不同簇中心點的距離來衡量聚類結果的質量。DBI的值越低&am…

QT的學習(一)

前言&#xff1a;距離上一次摸QT已經快10年了&#xff0c;時光匆匆&#xff0c;現在已經到6.9版本了 一、安裝QT 1.1、下載鏈接 https://mirrors.tuna.tsinghua.edu.cn/qt/official_releases/online_installers/ 這是國內鏡像&#xff0c;比官網快很多了&#xff0c;官網那個…

亞洲數字能源獨角獸的 “安全密碼”:Parasoft為星星充電筑牢軟件防線

當你在充電樁前等待愛車滿電時&#xff0c;是否想過&#xff1a;這看似簡單的充電過程&#xff0c;背后藏著多少軟件代碼的精密協作&#xff1f;作為亞洲數字能源領域的頭部企業&#xff0c;星星充電用 “移動能源網” 連接著千萬用戶與新能源世界&#xff0c;而支撐這一切的&a…

安裝Codex(需要用npm)

查看已經安裝的包 npm list -g --depth0 npm uninstall -g anthropic-ai/claude-code 如果要卸載什么東西 安裝Codex &#xff1a;npm i -g openai/codex https://openai.com/zh-Hant/codex/ 之后登錄gpt賬號&#xff0c;完成后就是下面的樣子

HarmonyOS 開發學習分享:從入門到認證的完整路徑

HarmonyOS 開發學習分享&#xff1a;從入門到認證的完整路徑 大家好&#xff01;我是趙老師&#xff0c;一個深耕鴻蒙生態的開發者。最近剛通過鴻蒙生態賦能資源豐富度建設活動的講師認證&#xff0c;想和大家分享一下 HarmonyOS 開發的學習心得和認證經驗。 我的鴻蒙開發經歷作…

使用Spring Boot DevTools快速重啟功能

背景 在Spring Boot項目中&#xff0c;修改一些簡單的代碼后&#xff0c;每次手動終止并啟動整個項目比較繁瑣且消耗時間。Spring Boot DevTools 提供了開發時的熱重啟功能&#xff0c;使得在開發過程中修改代碼后可以快速生效&#xff0c;而無需手動重啟整個應用&#xff0c;可…

7.4Element Plus 分頁與表格組件

el-pagination el-table 這兩個組件是后臺管理系統中最常用的數據展示與交互組合&#xff0c;通常配合使用實現 分頁加載、排序、篩選、操作 等功能。一、分頁組件 el-pagination用于控制大量數據的分頁展示。? 基本結構<el-paginationv-model:current-page"currentPa…

搭建機器學習模型的數據管道架構方案

本篇文章Designing Data Pipeline Architectures for Machine Learning Models適合對數據管道架構感興趣的讀者&#xff0c;亮點在于詳細解析了傳統數據倉庫、云原生數據湖和現代湖倉這三種架構&#xff0c;幫助理解如何將原始數據轉化為可操作的預測。文中還強調了不同架構的優…

GitHub 熱榜項目 - 日榜(2025-09-06)

GitHub 熱榜項目 - 日榜(2025-09-06) 生成于&#xff1a;2025-09-06 統計摘要 共發現熱門項目&#xff1a;15 個 榜單類型&#xff1a;日榜 本期熱點趨勢總結 本期GitHub熱榜顯示AI自動化與安全運維為核心趨勢。Bytebot、EvolutionAPI等AI代理項目凸顯自然語言交互和容器化…

Homebrew執行brew install出現錯誤(homebrew-bottles)

問題描述 在使用homebrew安裝軟件時&#xff0c;出現如下報錯&#xff1a; Downloading https://mirrors.aliyun.com/homebrew/homebrew-bottles/bottles-portable-ruby/portable ruby-3.4.5.arm64_big_sur.bottle.tar.gz curl: (22) The requested URL returned error: 404 …

23種設計模式——工廠方法模式(Factory Method Pattern)詳解

?作者簡介&#xff1a;大家好&#xff0c;我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式&#xff0c;持續分享Java技術內容。 &#x1f34e;個人主頁&#xff1a;Meteors.的博客 &#x1f49e;當前專欄&#xff1a;設計模式 ?特色專欄&#xff1a;知識分享 &#x…

NPU邊緣推理識物系統

目錄 NPU邊緣推理識物系統 一、項目簡介 二、硬件介紹 三、軟件設計 1、底層NPU推理代碼 2、應用層QT顯示代碼 四、項目成果展示 NPU邊緣推理識物系統 一、項目簡介 物品分類是計算機視覺的重要技術&#xff0c;本項目的核心是&#xff1a;使用NPU&#xff08;神經網絡…

C# WinForm分頁控件實現與使用詳解

C# WinForm分頁控件實現與使用詳解概述在WinForms應用程序開發中&#xff0c;數據分頁是常見的需求。本文將介紹如何實現一個功能完整的分頁控件&#xff0c;并在窗體中如何使用該控件進行數據分頁展示。分頁控件實現核心屬性與字段public partial class PageControl : UserCon…