Leetcode百題斬-二叉樹

二叉樹作為經典面試系列,那么當然要來看看。總計14道題,包含大量的簡單題,說明這確實是個比較基礎的專題。快速過快速過。

先構造一個二叉樹數據結構。


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;}public static TreeNode build(List<Integer> nodes) {if (nodes == null || nodes.isEmpty()) {return null;}List<TreeNode> treeList = new ArrayList<>();int nodePos = 0;int nodeLen = nodes.size();TreeNode root = new TreeNode(nodes.get(nodePos++));treeList.add(root);int treePos = 0;int treeLen = treeList.size();while (treePos < treeLen && nodePos < nodeLen) {TreeNode nowNode = treeList.get(treePos++);Integer nowVal = nodes.get(nodePos++);if (nowVal != null) {TreeNode leftNode = new TreeNode(nowVal);treeList.add(leftNode);nowNode.left = leftNode;}if (nodePos < nodeLen) {nowVal = nodes.get(nodePos++);if (nowVal != null) {TreeNode rightNode = new TreeNode(nowVal);treeList.add(rightNode);nowNode.right = rightNode;}}treeLen = treeList.size();}return root;}private List<Integer> levelOrderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();List<TreeNode> treeQueue = new ArrayList<>();if (root == null) {return Collections.emptyList();}treeQueue.add(root);int len = treeQueue.size();int pos = 0;int actualLen = len;while (pos < len) {for (int i = pos; i < len; i++) {TreeNode treeNode = treeQueue.get(i);if (treeNode == null) {if (i < actualLen) {result.add(null);}continue;}result.add(treeNode.val);treeQueue.add(treeNode.left);if (treeNode.left != null) {actualLen = treeQueue.size();}treeQueue.add(treeNode.right);if (treeNode.right != null) {actualLen = treeQueue.size();}len = treeQueue.size();}pos = len;}return result;}@Overridepublic String toString() {return levelOrderTraversal(this).toString();}
}

94. Binary Tree Inorder Traversal[Easy]

思路:中序遍歷,沒啥說的了,直接過

class Solution {public List<Integer> inorderTraversal(TreeNode root) {if (root == null) {return new ArrayList<>();}List<Integer> result = new ArrayList<>();result.addAll(inorderTraversal(root.left));result.add(root.val);result.addAll(inorderTraversal(root.right));return result;}
}

98. Validate Binary Search Tree[Medium]

思路:驗證二叉搜索樹,?完全可以用上面編號102題層序遍歷上面編號94題中序遍歷的代碼,最后判斷一下中序遍歷的結果是否遞增即可

class Solution {public boolean isValidBST(TreeNode root) {List<Integer> inorderTraversal = inorderTraversal(root);int len = inorderTraversal.size();for (int i = 1; i < len; i++) {if (inorderTraversal.get(i) <= inorderTraversal.get(i - 1)) {return false;}}return true;}
}

當然,用前一題的思路中序遍歷一下,然后再用一個變量來記錄當前遍歷的數值,可以完成優化

class Solution {private Integer current;public boolean isValidBST(TreeNode root) {if (root.left != null && !isValidBST(root.left)) {return false;}if (current != null && current >= root.val) {return false;}current = root.val;if (root.right != null && !isValidBST(root.right)) {return false;}return true;}
}

101. Symmetric Tree[Easy]

思路:判斷二叉樹是否對稱。最近寫回溯寫多了,不過這不是個回溯,這就是個正向遞歸,遞歸左右子樹判斷是否對稱即可

class Solution {public boolean isSymmetric(TreeNode root) {if (root == null) {return true;}return isSymmetric(root.left, root.right);}public boolean isSymmetric(TreeNode leftTree, TreeNode rightTree) {if (leftTree == null && rightTree == null) {return true;}if (!(leftTree != null && rightTree != null)) {return false;}if (leftTree.val != rightTree.val) {return false;}if (!isSymmetric(leftTree.left, rightTree.right)) {return false;}if (!isSymmetric(leftTree.right, rightTree.left)) {return false;}return true;}
}

102. Binary Tree Level Order Traversal[Medium]

思路:二叉樹層序遍歷,沒啥好說的,直接模擬隊列即可

class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<TreeNode> treeQueue = new ArrayList<>();List<List<Integer>> result = new ArrayList<>();if (root == null) {return result;}treeQueue.add(root);int len = treeQueue.size();int pos = 0;while (pos < len) {List<Integer> levelResult = new ArrayList<>();for (int i = pos; i < len; i++) {TreeNode treeNode = treeQueue.get(i);levelResult.add(treeNode.val);if (treeNode.left != null) {treeQueue.add(treeNode.left);}if (treeNode.right != null) {treeQueue.add(treeNode.right);}}pos = len;len = treeQueue.size();result.add(levelResult);}return result;}
}

104. Maximum Depth of Binary Tree[Easy]

思路:求樹的最大深度,這就是遞歸求左右子樹最大深度然后對比即可,真一行代碼搞定

class Solution {public int maxDepth(TreeNode root) {return root == null ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;}
}

105. Construct Binary Tree from Preorder and Inorder Traversal[Medium]

思路:根據前序遍歷和中序遍歷構造二叉樹,這又是一道再經典不過的題了。前序遍歷用于尋找父節點,推動遍歷子樹;中序遍歷則用于劃分左右子樹。

class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {Map<Integer, Integer> inorderMap = new HashMap<>();int len = inorder.length;for (int i = 0; i < len; i++) {inorderMap.put(inorder[i], i);}return buildTree(preorder, inorder, 0, len, 0, len, inorderMap);}private TreeNode buildTree(int[] preorder, int[] inorder, int preStartPos, int preEndPos, int inStartPos,int inEndPos, Map<Integer, Integer> inorderMap) {int root = preorder[preStartPos];if (preStartPos == preEndPos) {return new TreeNode(root);}int inRootPos = inorderMap.get(root);int leftLen = inRootPos - inStartPos;TreeNode leftTree = buildTree(preorder, inorder, preStartPos + 1, preStartPos + leftLen, inStartPos, inRootPos,inorderMap);TreeNode rightTree = buildTree(preorder, inorder, preStartPos + leftLen + 1, preEndPos, inRootPos + 1, inEndPos,inorderMap);return new TreeNode(root, leftTree, rightTree);}
}

108. Convert Sorted Array to Binary Search Tree[Easy]

思路:別看easy題就放飛自我了。將有序數組轉換為二叉搜索樹,不僅保證樹平衡,也要保證每個子樹平衡,因此也要用到遞歸的

class Solution {public TreeNode sortedArrayToBST(int[] nums) {return sortedArrayToBST(nums, 0, nums.length);}private TreeNode sortedArrayToBST(int[] nums, int begin, int end) {if (begin >= end) {return null;}int mid = (begin + end) / 2;TreeNode root = new TreeNode(nums[mid]);TreeNode leftTree = sortedArrayToBST(nums, begin, mid);TreeNode rightTree = sortedArrayToBST(nums, mid + 1, end);root.left = leftTree;root.right = rightTree;return root;}
}

114. Flatten Binary Tree to Linked List[Medium]

思路:將二叉樹壓成鏈。這就涉及到二叉樹斷鏈和合鏈操作了。想清楚寫個遞歸即可

class Solution {public void flatten(TreeNode root) {flattenTree(root);}private TreeNode flattenTree(TreeNode root) {if (root == null) {return null;}TreeNode leftTree = flattenTree(root.left);TreeNode rightTree = flattenTree(root.right);if (leftTree != null) {root.right = leftTree;root.left = null;if (rightTree != null) {while (leftTree.right != null) {leftTree = leftTree.right;}leftTree.right = rightTree;}}return root;}
}

199. Binary Tree Right Side View[Medium]

思路:求二叉樹的右視圖,這個就完全可以用上面編號102題層序遍歷的代碼,然后取每層最后一個即可

class Solution {public List<Integer> rightSideView(TreeNode root) {List<List<Integer>> levelOrder = levelOrder(root);return levelOrder.stream().map(list -> list.get(list.size() - 1)).collect(Collectors.toList());}
}

當然,也可以將層序遍歷的代碼拿來優化一下,不需要記錄層序遍歷多余的節點,只需要記錄每層末節點即可

class Solution {public List<Integer> rightSideView(TreeNode root) {List<TreeNode> treeQueue = new ArrayList<>();List<Integer> result = new ArrayList<>();if (root == null) {return Collections.emptyList();}treeQueue.add(root);int len = treeQueue.size();int pos = 0;while (pos < len) {int lastNode = root.val;for (int i = pos; i < len; i++) {TreeNode treeNode = treeQueue.get(i);lastNode = treeNode.val;if (treeNode.left != null) {treeQueue.add(treeNode.left);}if (treeNode.right != null) {treeQueue.add(treeNode.right);}}pos = len;len = treeQueue.size();result.add(lastNode);}return result;}
}

230. Kth Smallest Element in a BST[Medium]

思路:求二叉搜索樹的第k小值,又可以用到上面編號94題中序遍歷的代碼,然后取遍歷數組中的第k個即可

class Solution {public int kthSmallest(TreeNode root, int k) {List<Integer> inorderTraversal = inorderTraversal(root);return inorderTraversal.get(k - 1);}
}

當然,與上一題同樣的原理,優化一下,用一個變量來記錄一下當前遍歷到的位置,這樣就可以在搜索到結果的時候提前結束,降低時耗

class Solution {private int now = 1;public int kthSmallest(TreeNode root, int k) {if (root == null) {return -1;}int leftValue = kthSmallest(root.left, k);if (leftValue != -1) {return leftValue;}if (now == k) {return root.val;}now++;return kthSmallest(root.right, k);}
}

437. Path Sum III[Medium]

思路:求二叉樹中路徑和為特定樹的路徑個數。這一題有一點點樹上DP的感覺,每個節點分別往左右子樹上遞歸,分為計算該節點和不計算該結點進行轉移。最后注意一個小細節,就是要注意邊界問題,多個數的和是很可能超int邊界的,注意要開成long

class Solution {public int pathSum(TreeNode root, int targetSum) {return pathSum(root, targetSum, true) + pathSum(root, targetSum, false);}private int pathSum(TreeNode root, long targetSum, boolean include) {int count = 0;if (root == null) {return count;}if (include) {if (root.val == targetSum) {count++;}count += pathSum(root.left, targetSum - root.val, true);count += pathSum(root.right, targetSum - root.val, true);} else {count += pathSum(root.left, targetSum, true);count += pathSum(root.right, targetSum, true);count += pathSum(root.left, targetSum, false);count += pathSum(root.right, targetSum, false);}return count;}
}

求和問題,當然再來一套前綴和。經典的字符串前綴和可以看我之前的哈希系列

class Solution {public int pathSum(TreeNode root, int targetSum) {HashMap<Long, Integer> sumMap = new HashMap<>();sumMap.put(0L, 1);return preSumPre(root, targetSum, sumMap, 0);}private int preSumPre(TreeNode root, int targetSum, Map<Long, Integer> sumMap, long currentSum) {int count = 0;if (root == null) {return count;}currentSum += root.val;if (sumMap.containsKey(currentSum - targetSum)) {count += sumMap.get(currentSum - targetSum);}sumMap.put(currentSum, sumMap.getOrDefault(currentSum, 0) + 1);count += preSumPre(root.left, targetSum, sumMap, currentSum);count += preSumPre(root.right, targetSum, sumMap, currentSum);sumMap.put(currentSum, sumMap.getOrDefault(currentSum, 0) - 1);return count;}
}

543. Diameter of Binary Tree[Easy]

思路:求二叉樹最長路徑。首先要遞歸求每個子樹的最長路徑,即等于左右子樹的高度和。遞歸函數將子樹高度返回,用一個單獨的變量記錄當前最長路徑并在每個子樹內比較更新即可

class Solution {private int maxLength = 0;public int diameterOfBinaryTree(TreeNode root) {getLength(root);return maxLength;}private int getLength(TreeNode root) {if (root == null) {return 0;}int leftLength = getLength(root.left);int rightLength = getLength(root.right);if (leftLength + rightLength > maxLength) {maxLength = leftLength + rightLength;}return Math.max(leftLength, rightLength) + 1;}
}

236. Lowest Common Ancestor of a Binary Tree[Medium]

這就是前兩天剛做過的通義app面試題,關于LCA的問題我專門特地整理了一下,感興趣可以前去看看:

最近公共祖先(LCA)

226. Invert Binary Tree[Easy]

偶然發現,這題我在五年前校招刷題的時候也寫過,當時的鏈接:二叉樹翻轉鏈接

左右子樹遞歸交換一下即可

class Solution {public TreeNode invertTree(TreeNode root) {if (root == null) {return null;}TreeNode left = invertTree(root.left);TreeNode right = invertTree(root.right);root.left = right;root.right = left;return root;}
}

再來看一下當時我這題,我把他和另兩道鏈表的題總結在了一起,剛好這個二叉樹專題就要結束了,順便預告溫習一下百題斬的下一個專題,就是鏈表專題

最后,完結撒花,下個專題再見

?

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

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

相關文章

Asp.Net Core 如何配置在Swagger中帶JWT報文頭

文章目錄 前言一、配置方法二、使用1、運行應用程序并導航到 /swagger2、點擊右上角的 Authorize 按鈕。3、輸入 JWT 令牌&#xff0c;格式為 Bearer your_jwt_token。4、后續請求將自動攜帶 Authorization 頭。 三、注意事項總結 前言 配置Swagger支持JWT 一、配置方法 在 …

MySQL 定時邏輯備份

文章目錄 配置密碼編寫備份腳本配置權限定時任務配置檢查效果如果不想保留明文密碼手工配置備份密碼修改備份命令 配置密碼 cat >> /root/.my.cnf <<"EOF" [client] userroot passwordYourPassword EOF編寫備份腳本 cat > /usr/local/bin/mysql_dum…

在qt中使用c++實現與Twincat3 PLC變量通信

這是一個只針對新手的教程&#xff0c;下載安裝就不說了&#xff0c;我下的是TC31-Full-Setup.3.1.4024.66.exe是這個版本&#xff0c;其他版本應該問題不大。 先創建一個項目 選中SYSTEM&#xff0c;在右側點擊Choose Target&#xff08;接下來界面跟我不一樣沒關系&#xf…

云原生微服務devops項目管理英文表述詳解

文章目錄 1.云原生CNCF trail map云原生技術棧路線圖 2. 微服務單體應用與微服務應用架構區別GraphQLKey differences: GraphQL and REST 3.容器化&編排dockerKubernetesContainers and ContainerizationContainer Basics 4. DevOps & CI/CDTerms and Definitions 5.Ag…

pyside 使用pyinstaller導出exe(含ui文件)

第一步&#xff1a;首先確保安裝好pyinstall&#xff0c;終端運行 pyinstaller -w main.py 生成兩個文件夾 打開exe文件報錯&#xff0c;問題是ui文件找不到 第二步&#xff1a;將ui文件復制到exe所在文件夾&#xff0c;打開成功 ![在這里插入圖片描述](https://i-blog.csdni…

kerberos在無痕瀏覽器 獲取用戶信息失敗 如何判斷是否無痕瀏覽器

kerberos在無痕瀏覽器 獲取用戶信息失敗 如何判斷是否無痕瀏覽器 js 代碼 其他地方用直接導入js getCurrentUserId 這是自己后端獲取 域賬號地址 我是成功返回200 //true普通瀏覽器 fasle 無痕瀏覽器 export const checkBrowserMode async () > {try {const response a…

HTML 計算網頁的PPI

HTML 計算網頁的PPI vscode上安裝live server插件&#xff0c;可以實時看網頁預覽 有個疑問&#xff1a; 鴻蒙density是按照類別寫死的嗎&#xff0c;手機520dpi 折疊屏426dpi 平板360dpi <html lang"en" data - overlayscrollbars - initialize><header&…

華為OD機試真題——Boss的收入(分銷網絡提成計算)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳實現

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

<el-date-picker>組件傳參時,選中時間和傳參偏差8小時

遇到一個bug&#xff0c;不仔細看&#xff0c;都不一定能發現&#xff0c;bug描述&#xff1a;我們有一個搜索框&#xff0c;里面有一個時間選擇器&#xff0c;當我使用<el-date-picker>時&#xff0c;我發現當我選擇時分秒之后&#xff0c;顯示都正常&#xff0c;但是當…

uni-app開發特殊社交APP

uni-app開發特殊社交APP 目錄 1.展示APP功能 2.展示項目結構 3.關于我的GitHub 引言 博主最近自己在GitHub上面上傳了一個關于社交軟件的項目&#xff08;該項目早已開發完畢&#xff09;, 這個社交軟件比較特殊, 被稱之為blind-date&#xff0c; blind-date 是基于 uni-…

深入研究Azure 容器網絡接口 (CNI) overlay

啟用cni overlay 在通過portal創建aks的時候,在networking配置上,選中下面的選項即可啟用。 通過CLI創建AKS 要創建具有 CNI 覆蓋網絡的 AKS 群集,需要在創建群集時指定 --network-plugin azure 和 --network-plugin-mode 覆蓋選項。 還需要指定 --pod-cidr 選項來定義群…

Docker 部署項目

使用 Docker 部署項目是一個很好的選擇&#xff0c;可以避免服務器環境不兼容的問題&#xff0c;并且能夠實現一致性和可移植性。我會給你一個詳細的步驟&#xff0c;幫你從零開始理解 Docker&#xff0c;最終在服務器上部署 Roop 項目。 1. 安裝 Docker 首先&#xff0c;你需…

excel表格記賬 : 操作單元格進行加減乘除 | Excel中Evaluate函數

文章目錄 引用I 基礎求和∑II Excel中Evaluate函數基于字符串表達式進行計算用法案例 :基于Evaluate實現匯率計算利潤知識擴展在單元格內的換行選擇整列單元格引用 需求: 基于匯率計算利潤,調整金額以及進匯率和出匯率自動算出利潤,已經統計總利潤。 基于Evaluate實現匯率計…

vue+ts+TinyEditor 是基于 Quill 2.0 開發的富文本編輯器,提供豐富的擴展功能,適用于現代 Web 開發的完整安裝使用教程

簡介 TinyEditor 是基于 Quill 2.0 開發的富文本編輯器&#xff0c;提供豐富的擴展功能&#xff0c;適用于現代 Web 開發。具備模塊化設計、輕量級架構和高度可定制化特性&#xff0c;支持多種插件擴展&#xff0c;滿足不同場景需求。 核心特性 基于 Quill 2.0 的現代化架構模…

matlab實現激光腔長計算滿足熱透鏡效應

激光腔長計算與熱透鏡效應補償 在全固態激光器中&#xff0c;熱透鏡效應是一個重要的問題&#xff0c;因為它會影響激光的光束質量和輸出功率。以下是如何計算激光腔長并考慮熱透鏡效應的方法&#xff0c;以及一些補償技術。 1. 激光腔長計算 激光腔長的計算需要考慮激光晶體…

Science Robotics 具身智能驅動的空中物理交互新范式:結合形態和傳感,與非結構化環境進行穩健交互

隨著科技的飛速發展&#xff0c;無人機技術已從單純的遠程感知擴展到與環境的物理交互領域&#xff0c;為可持續發展目標的實現提供了新的可能性。傳統的空中物理交互方法依賴于復雜的控制策略和精確的環境建模&#xff0c;盡管能夠實現高精度操作&#xff0c;但其在非結構化自…

圖神經網絡在信息檢索重排序中的應用:原理、架構與Python代碼解析

現代信息檢索系統和搜索引擎普遍采用兩階段檢索架構&#xff0c;在人工智能應用中也被稱為檢索增強生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;。在初始檢索階段&#xff0c;系統采用高效的檢索方法&#xff0c;包括詞匯檢索算法&#xff08;如BM25&…

List 源碼翻譯

List 源碼翻譯-jdk1.8 翻譯來自 AI 大模型。 全部源碼翻譯下載 /** 版權所有 (c) 1997, 2014, Oracle 和/或其附屬公司。保留所有權利。* ORACLE 專有/機密。使用受許可條款約束。*********************/package java.util;import java.util.function.UnaryOperator;/*** 有序…

Vscode 解決 #include <> 找不到的問題

本人遇到的情況, 使用 ROS 的過程中, 發現 #include <pcl/point_types.h> 不被 VScode 識別, 在 AI 的幫助下解決了該問題, 現總結如下: 1. 查看是否有相應的文件 Linux 下, point_types.h 的存儲路徑一般為: /usr/include/pcl-1.x (我的路徑是 /usr/include/pcl-1.12)…