Leetcode 刷題記錄 11 —— 二叉樹第二彈

本系列為筆者的 Leetcode 刷題記錄,順序為 Hot 100 題官方順序,根據標簽命名,記錄筆者總結的做題思路,附部分代碼解釋和疑問解答,01~07為C++語言,08及以后為Java語言。

01 二叉樹的層序遍歷

在這里插入圖片描述

在這里插入圖片描述

/*** 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 List<List<Integer>> levelOrder(TreeNode root) {//廣度優先遍歷 queue//1.創建queue集合,添加首節點Deque<TreeNode> queue = new LinkedList<>();queue.offer(root);//2.遍歷tree,取出結點,判斷結點情況List<List<Integer>> results = new ArrayList<>();if(root == null){return results;}while(!queue.isEmpty()){int size = queue.size();List<Integer> result = new ArrayList<>();for(int i=0; i<size; i++){TreeNode node = queue.poll();result.add(node.val);//3.添加左右孩子結點if(node.left != null){queue.offer(node.left);}if(node.right != null){queue.offer(node.right);}}results.add(result);}return results;}
}

02 將有序數組轉換為二叉搜索樹

在這里插入圖片描述

在這里插入圖片描述

/*** 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 sortedArrayToBST(int[] nums) {}
}

給定二叉搜索樹的中序遍歷,是否可以唯一地確定二叉搜索樹?答案是否定的。

如果增加一個限制條件,即要求二叉搜索樹的高度平衡,是否可以唯一地確定二叉搜索樹?答案仍然是否定的。

直觀地看,我們可以選擇中間數字作為二叉搜索樹的根節點,這樣分給左右子樹的數字個數相同或只相差 1,可以使得樹保持平衡。

方法一:遞歸

BST 是 Binary Search Tree(二叉搜索樹)的縮寫。

class Solution {public TreeNode sortedArrayToBST(int[] nums) {//1.構建遞歸函數,傳遞左右區間參數return helper(nums, 0, nums.length-1);}public TreeNode helper(int[] nums, int left, int right){if(left > right){ //特殊情況判斷return null;}//2.添加當前root結點int mid = (left + right) / 2;TreeNode root = new TreeNode(nums[mid]);//3.遞歸添加左右孩子結點root.left = helper(nums, left, mid - 1);root.right = helper(nums, mid + 1, right);return root;}
}

03 驗證二叉搜索樹

在這里插入圖片描述

在這里插入圖片描述

/*** 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 isValidBST(TreeNode root) {}
}

這啟示我們設計一個遞歸函數 helper(root, lower, upper) 來遞歸判斷,函數表示考慮以 root 為根的子樹,判斷子樹中所有節點的值是否都在 (l,r) 的范圍內(注意是開區間)。如果 root 節點的值 val 不在 (l,r) 的范圍內說明不滿足條件直接返回,否則我們要繼續遞歸調用檢查它的左右子樹是否滿足,如果都滿足才說明這是一棵二叉搜索樹。

方法一:遞歸

class Solution {public boolean isValidBST(TreeNode root) {//1.構建遞歸函數,傳遞左右區間參數return helper(root, Long.MIN_VALUE, Long.MAX_VALUE);}public boolean helper(TreeNode root, long lower, long upper){if(root == null){ //特殊情況判斷return true;}//2.判斷當前root結點if(root.val <= lower || root.val >= upper){return false;}//3.遞歸判斷左右孩子結點return helper(root.left, lower, root.val) && helper(root.right, root.val, upper);}
}

Long.MIN_VALUELong.MAX_VALUE是啥?

  • Long.MIN_VALUE-2^63,即 -9,223,372,036,854,775,808。代表 long 類型變量可以存儲的最小值。
  • Long.MAX_VALUE2^63 - 1,即 9,223,372,036,854,775,807。代表 long 類型變量可以存儲的最大值。

方法二:中序遍歷

class Solution {public boolean isValidBST(TreeNode root) {if(root == null){return true;}//queue: 創建 -> 當前 -> 孩子//stack: 創建 -> 左移 -> 右移//1.創建Deque<TreeNode> stack = new LinkedList<>();long inorder = Long.MIN_VALUE;while(!stack.isEmpty() || root != null){//2.左移while(root != null){stack.push(root);root = root.left;}root = stack.pop();if(root.val <= inorder){return false;}inorder = root.val;//3.右移root = root.right;}return true;}
}

04 二叉搜索樹中第K小的元素

在這里插入圖片描述

在這里插入圖片描述

方法一:遞歸

/*** 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 {int flag1, flag2;public int kthSmallest(TreeNode root, int k) {flag1 = k;flag2 = 0;return inorder(root);}//1.創建public int inorder(TreeNode root){if(root == null){return -1;}//2.左右孩子結點int left = inorder(root.left);if(left != -1){return left;}flag2++;if(flag2 == flag1){return root.val;}//3.返回return inorder(root.right);}
}

方法二:棧

05 二叉樹的右視圖

在這里插入圖片描述

在這里插入圖片描述

/*** 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 List<Integer> rightSideView(TreeNode root) {}
}

方法一:深度優先搜索(stack)

class Solution {public List<Integer> rightSideView(TreeNode root) {Map<Integer, Integer> map = new HashMap<>(); //深度,valint maxDepth = -1; //標記//1.創建并加入Deque<TreeNode> nodeStack = new LinkedList<>();Deque<Integer> depthStack = new LinkedList<>();nodeStack.push(root);depthStack.push(0);while(!nodeStack.isEmpty()){//2.彈出并判斷TreeNode node = nodeStack.pop();int depth = depthStack.pop();if(node != null){maxDepth = Math.max(maxDepth, depth); //標記更新//?if(!map.containsKey(depth)){map.put(depth, node.val);}//3.左右孩子結點nodeStack.push(node.left);nodeStack.push(node.right);depthStack.push(depth + 1);depthStack.push(depth + 1);}}//?List<Integer> result = new ArrayList<>();for(int i=0; i<=maxDepth; i++){result.add(map.get(i));}return result;}
}

Deque是啥意思?

DequeDouble Ended Queue(雙端隊列) 的縮寫,是一個接口,常用實現有LinkedListArrayDeque,既可以用作隊列(先進先出),也可以用作(后進先出)。

② 這個代碼是怎么保證每次棧彈出的都是沒加入map的最右端結點?

因為棧是后進先出,右孩子會先被彈出訪問。所以在訪問該層節點時,第一個被訪問到的節點是右孩子,也就是該層最右邊的節點。

③ 為什么maxDepth 賦值為0,會出現解答錯誤?

  • 當樹為空時,沒有層被訪問,maxDepth 應該還是未初始化狀態。
  • 如果用 int maxDepth = 0;,說明認為至少訪問了一層深度(深度0)
  • 代碼循環從 0maxDepth,會執行一次。
  • 但實際上沒有節點,也沒往map中放任何數據,所以map.get(0)會返回null,結果列表加了一個null
  • 導致與預期的空列表([])不符。

方法二:廣度優先搜索(queue)

class Solution {public List<Integer> rightSideView(TreeNode root) {Map<Integer, Integer> rightmostValueAtDepth = new HashMap<Integer, Integer>();int max_depth = -1;Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();Queue<Integer> depthQueue = new LinkedList<Integer>();nodeQueue.add(root);depthQueue.add(0);while (!nodeQueue.isEmpty()) {TreeNode node = nodeQueue.remove();int depth = depthQueue.remove();if (node != null) {// 維護二叉樹的最大深度max_depth = Math.max(max_depth, depth);// 由于每一層最后一個訪問到的節點才是我們要的答案,因此不斷更新對應深度的信息即可rightmostValueAtDepth.put(depth, node.val);nodeQueue.add(node.left);nodeQueue.add(node.right);depthQueue.add(depth + 1);depthQueue.add(depth + 1);}}List<Integer> rightView = new ArrayList<Integer>();for (int depth = 0; depth <= max_depth; depth++) {rightView.add(rightmostValueAtDepth.get(depth));}return rightView;}
}

為什么最后訪問到的才是最右邊節點?

  • rightmostValueAtDepth.put(depth, node.val); 不斷地更新當前深度對應的節點值。
  • 訪問順序是每層從左到右,意味著:
    • 最開始訪問的節點會寫入該層的值。
    • 后面訪問的節點會覆蓋之前的值。
    • 因為是從左往右訪問,最后訪問的節點就是最右節點。
  • 最終 “rightmostValueAtDepth” 保存的,正是每一層的最右邊節點值。

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

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

相關文章

【R語言科研繪圖】

R語言在繪制SCI期刊圖像時具有顯著優勢&#xff0c;以下從功能、靈活性和學術適配性三個方面分析其適用性&#xff1a; 數據可視化庫豐富 R語言擁有ggplot2、lattice、ggpubr等專業繪圖包&#xff0c;支持生成符合SCI期刊要求的高分辨率圖像&#xff08;如TIFF/PDF格式&#…

【Node.js】Web開發框架

個人主頁&#xff1a;Guiat 歸屬專欄&#xff1a;node.js 文章目錄 1. Node.js Web框架概述1.1 Web框架的作用1.2 Node.js主要Web框架生態1.3 框架選擇考慮因素 2. Express.js2.1 Express.js概述2.2 基本用法2.2.1 安裝Express2.2.2 創建基本服務器 2.3 路由2.4 中間件2.5 請求…

PDF 轉 JPG 圖片小工具:CodeBuddy 助力解決轉換痛點

本文所使用的 CodeBuddy 免費下載鏈接&#xff1a;騰訊云代碼助手 CodeBuddy - AI 時代的智能編程伙伴 前言 在數字化辦公與內容創作的浪潮中&#xff0c;將 PDF 文件轉換為 JPG 圖片格式的需求日益頻繁。無論是學術文獻中的圖表提取&#xff0c;還是宣傳資料的視覺化呈現&am…

Linux 文件系統層次結構

Linux 的文件系統遵循 Filesystem Hierarchy Standard (FHS) 標準&#xff0c;其目錄結構是層次化的&#xff0c;每個目錄都有明確的用途。以下是 Linux 中部分目錄的作用解析&#xff1a; 1. 根目錄 / 作用&#xff1a;根目錄是整個文件系統的頂層目錄&#xff0c;所有其他目…

密碼學標準(Cryptography Standards)介紹

密碼學標準(Cryptography Standards)是為確保信息安全傳輸、存儲和處理而制定的一系列技術規范和協議,廣泛應用于通信、金融、互聯網等領域。以下從分類、主流標準、應用場景和發展趨勢四個方面進行詳細介紹: 一、密碼學標準的分類 密碼學標準可根據技術原理和應用場景分…

ubuntu 22.04安裝和使用docker介紹

docker安裝和使用 準備環境常見的docker操作linux系統常用的配置卸載docker 準備環境 本機環境&#xff1a; Linux yz-MS-7E06 6.8.0-59-generic #61~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 17:03:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux安裝依賴軟件&#xff1a;…

obsidian 中的查找和替換插件,支持正則

最近用著 obsidian 時&#xff0c;發現想要在當前文檔中 查找和替換 內容時&#xff0c;沒有自動查找和替換的功能&#xff0c;去插件市場查找也沒有發現好用的插件&#xff0c;那就自己寫一個吧。 全程用的 AI 來寫的&#xff0c;當然&#xff0c;我對 JS/CSS/TypeScript 等沒…

針對vue項目的webpack優化攻略

一、開發階段優化 1. 熱更新加速&#xff08;HMR&#xff09; // vue.config.js module.exports {devServer: {hot: true, // 開啟熱更新injectClient: true, // 自動注入HMR客戶端watchOptions: {ignored: /node_modules/, // 忽略node_modules變化aggregateTimeout: 300…

BTC官網關注巨鯨12億美元平倉,XBIT去中心化交易平臺表現穩定

在全球加密貨幣市場波動加劇的背景下&#xff0c;2025年5月25日傳出重磅消息。據今日最新國際報道&#xff0c;知名巨鯨James Wynn完全平倉價值12億美元的BTC多頭倉位&#xff0c;整體盈利約845萬美元&#xff0c;此舉引發市場廣泛關注。與此同時&#xff0c;收益型穩定幣市場迎…

在WPF中添加動畫背景

在WPF中添加動畫背景 在WPF中創建動畫背景可以大大增強應用程序的視覺效果。以下是幾種實現動畫背景的方法&#xff1a; 方法1&#xff1a;使用動畫ImageBrush&#xff08;圖片輪播&#xff09; <Window x:Class"AnimatedBackground.MainWindow"xmlns"htt…

單點擊登錄sso實現

一、單點登錄&#xff08;SSO&#xff09;是什么&#xff1f; 核心定義 單點登錄&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一種身份認證解決方案&#xff0c;允許用戶通過一次登錄訪問多個相互信任的應用系統。其核心邏輯是統一認證中心與分布式會話管理&…

JavaWebsocket-demo

Websocket客戶端 pom依賴 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.4.0</version></dependency>客戶端代碼片段 Component Slf4j public class PositionAlarmL…

Java Collection(集合) 接口

Date: 2025-05-21 20:21:32 author: lijianzhan Java 集合框架提供了一組接口和類&#xff0c;以實現各種數據結構和算法。 以下是關于 Java 集合的核心內容說明&#xff1a; /*** Java Collection Framework 說明&#xff1a;** 在 Java 中&#xff0c;集合&#xff08;Collec…

讓MySQL更快:EXPLAIN語句詳盡解析

前言 在數據庫性能調優中&#xff0c;SQL 查詢的執行效率是影響系統整體性能的關鍵因素之一。MySQL 提供了強大的工具——EXPLAIN 語句&#xff0c;幫助開發者和數據庫管理員深入分析查詢的執行計劃&#xff0c;從而發現潛在的性能瓶頸并進行針對性優化。 EXPLAIN 語句能夠模…

Java基礎 Day20

一、HashSet 集合類 1、簡介 HashSet 集合底層采取哈希表存儲數據 底層是HashMap 不能使存取有序 JDK8之前的哈希表是數組和鏈表&#xff0c;頭插法 JDK8之后的哈希表是數組、鏈表和紅黑樹&#xff0c;尾插法 2、存儲元素 &#xff08;1&#xff09;如果要保證元素的唯…

2505C++,32位轉64位

原文 假設有個想要將一個32位值傳遞給一個帶64位值的函數的函數.你不關心高32位的內容,因為該值是傳遞給回調函數的直通值,回調函數會把它截斷為32位值. 因此,你都擔心編譯器一般生成的將32位值擴展到64位值的那條指令的性能影響. 我懷疑這條指令不是程序中的性能瓶頸. 我想出…

光伏電站及時巡檢:守護清潔能源的“生命線”

在“雙碳”目標驅動下&#xff0c;光伏電站作為清潔能源的主力軍&#xff0c;正以年均20%以上的裝機增速重塑全球能源格局。然而&#xff0c;這些遍布荒漠、屋頂的“光伏矩陣”并非一勞永逸的能源提款機&#xff0c;其穩定運行高度依賴精細化的巡檢維護。山東棗莊觸電事故、衢州…

C++初階-list的使用2

目錄 1.std::list::splice的使用 2.std::list::remove和std::list::remove_if的使用 2.1remove_if函數的簡單介紹 基本用法 函數原型 使用函數對象作為謂詞 使用普通函數作為謂詞 注意事項 復雜對象示例 2.2remove與remove_if的簡單使用 3.std::list::unique的使用 …

OpenHarmony平臺驅動使用(一),ADC

OpenHarmony平臺驅動使用&#xff08;一&#xff09; ADC 概述 功能簡介 ADC&#xff08;Analog to Digital Converter&#xff09;&#xff0c;即模擬-數字轉換器&#xff0c;可將模擬信號轉換成對應的數字信號&#xff0c;便于存儲與計算等操作。除電源線和地線之外&#…

CSS【詳解】彈性布局 flex

適用場景 一維&#xff08;行或列&#xff09;布局 基本概念 包裹所有被布局元素的父元素為容器 所有被布局的元素為項目 項目的排列方向&#xff08;垂直/水平&#xff09;為主軸 與主軸垂直的方向交交叉軸 容器上啟用 flex 布局 將容器的 display 樣式設置為 flex 或 i…