代碼隨想錄算法訓練營十六天|二叉樹part06

LeetCode 530 二叉搜索樹的最小絕對差

題目鏈接:530. 二叉搜索樹的最小絕對差 - 力扣(LeetCode)

給你一個二叉搜索樹的根節點 root ,返回 樹中任意兩不同節點值之間的最小差值 。

差值是一個正數,其數值等于兩值之差的絕對值。

示例 1:


輸入:root = [4,2,6,1,3]
輸出:1
示例 2:


輸入:root = [1,0,48,null,null,12,49]
輸出:1

?首先將二叉搜索樹中序遍歷轉化為有序數組,其實在遍歷的過程中就可以直接計算了。

需要用一個pre節點來記錄當前節點的前一個節點。

遞歸法:

class Solution {int res=Integer.MAX_VALUE;TreeNode pre=null;public int getMinimumDifference(TreeNode root) {//遞歸if(root==null)return 0;getMinimumDifference(root.left);if(pre!=null)res=Math.min(res,root.val-pre.val);pre=root;getMinimumDifference(root.right);return res;}
}

迭代法:

class Solution {public int getMinimumDifference(TreeNode root) {//迭代int res=Integer.MAX_VALUE;TreeNode pre=null;Stack<TreeNode> st=new Stack<>();st.push(root);while(!st.isEmpty()){TreeNode node=st.pop();if(node!=null){if(node.right!=null)st.push(node.right);st.push(node);st.push(null);if(node.left!=null)st.push(node.left);}else{TreeNode tmp=st.pop();if(pre!=null)res=Math.min(res,tmp.val-pre.val);pre=tmp;}}return res;}
}

LeetCode 501 二叉搜索樹中的眾數

題目鏈接:501. 二叉搜索樹中的眾數 - 力扣(LeetCode)

給你一個含重復值的二叉搜索樹(BST)的根節點 root ,找出并返回 BST 中的所有 眾數(即,出現頻率最高的元素)。

如果樹中有不止一個眾數,可以按 任意順序 返回。

假定 BST 滿足如下定義:

結點左子樹中所含節點的值 小于等于 當前節點的值
結點右子樹中所含節點的值 大于等于 當前節點的值
左子樹和右子樹都是二叉搜索樹

示例 1:


輸入:root = [1,null,2,2]
輸出:[2]
示例 2:

輸入:root = [0]
輸出:[0]

?最直觀的方法就是把整個樹遍歷了,用map統計頻率,把頻率排序,最后取前面高頻的元素的集合。

class Solution {public int[] findMode(TreeNode root) {Map<Integer,Integer> map=new HashMap<>();Stack<TreeNode> st=new Stack<>();if(root!=null)st.push(root);while(!st.isEmpty()){TreeNode node=st.pop();if(node!=null){if(node.right!=null)st.push(node.right);st.push(node);st.push(null);if(node.left!=null)st.push(node.left);}else{node=st.pop();if(!map.containsKey(node.val))map.put(node.val,0);else map.put(node.val,map.get(node.val)+1);}}int maxCount=0;List<Integer> list=new ArrayList<>();for(Integer obj:map.keySet()){if(map.get(obj)>maxCount)maxCount=map.get(obj);}for(Integer obj:map.keySet()){if(map.get(obj)==maxCount)list.add(obj);}int res[]=new int[list.size()];for(int i=0;i<list.size();i++){res[i]=list.get(i);}return res;}
}

但既然是二叉搜索樹,它中序遍歷就是有序的,遍歷有序數組的元素出現頻率,從頭遍歷,那么一定是兩個相鄰元素作比較,然后把出現頻率最高的元素輸出就行了。

需要定義一個pre節點,是當前節點的前一個節點,每次將二者作比較。

if(pre==null)count=1;
else if(pre!=null&&tmp.val==pre.val)count++;
else count=1;
pre=tmp;

因為可能有多個眾數,所以應該要先遍歷一遍數組,找出最大頻率,然后再遍歷一遍數組把出現頻率為該最大頻率的元素放入結果中。這樣的方式需要遍歷兩次數組。

那如何只遍歷一遍呢?

如果當前元素出現頻率等于最大頻率,就把這個元素加入到結果集中;如果當前元素出現頻率大于最大頻率,先更新最大頻率,然后清空結果集,因為結果集之前的元素都失效了,然后再把當前元素加入結果集中。

完整代碼如下:

class Solution {public int[] findMode(TreeNode root) {int count=0;int maxCount=0;Stack<TreeNode> st=new Stack<>();List<Integer> list=new ArrayList<>();TreeNode pre=null;if(root!=null)st.push(root);while(!st.isEmpty()){TreeNode node=st.pop();if(node!=null){if(node.right!=null)st.push(node.right);st.push(node);st.push(null);if(node.left!=null)st.push(node.left);}else{TreeNode tmp=st.pop();if(pre==null)count=1;else if(pre!=null&&tmp.val==pre.val)count++;else count=1;pre=tmp;if(count==maxCount)list.add(tmp.val);else if(count>maxCount){maxCount=count;list.clear();list.add(tmp.val);}}}int[] res=new int[list.size()];for(int i=0;i<list.size();i++){res[i]=list.get(i);}return res;}
}

遞歸寫法:

class Solution {List<Integer> list=new ArrayList<>();int count=0;int maxCount=0;TreeNode pre=null;public int[] findMode(TreeNode root) {//遞歸if(root==null)return null;findMode(root.left);if(pre==null)count=1;else if(pre!=null&&pre.val==root.val)count++;else count=1;pre=root;if(count==maxCount)list.add(root.val);else if(count>maxCount){maxCount=count;list.clear();list.add(root.val);}findMode(root.right);int[] res=new int[list.size()];for(int i=0;i<list.size();i++){res[i]=list.get(i);}return res;}
}

LeetCode 236 二叉樹的最近公共祖先

題目鏈接:236. 二叉樹的最近公共祖先 - 力扣(LeetCode)

給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。

百度百科中最近公共祖先的定義為:“對于有根樹 T 的兩個節點 p、q,最近公共祖先表示為一個節點 x,滿足 x 是 p、q 的祖先且 x 的深度盡可能大(一個節點也可以是它自己的祖先)。”

示例 1:


輸入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
輸出:3
解釋:節點 5 和節點 1 的最近公共祖先是節點 3 。
示例 2:


輸入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
輸出:5
解釋:節點 5 和節點 4 的最近公共祖先是節點 5 。因為根據定義最近公共祖先節點可以為節點本身。
示例 3:

輸入:root = [1,2], p = 1, q = 2
輸出:1

條件:

  • 樹中節點數目在范圍?[2, 105]?內。
  • -109 <= Node.val <= 109
  • 所有?Node.val?互不相同?。
  • p != q
  • p?和?q?均存在于給定的二叉樹中。

?思路:首先想的是要是能自底向上查找就好了,這樣就可以找到公共祖先了。

那么如何自底向上查找?

回溯法,后序遍歷可以根據左右子樹的返回值來處理中節點的邏輯。

如何判斷一個節點是節點p和節點q的公共祖先?

如果找出一個節點,發現左子樹出現節點p,右子樹出現節點q,或者左子樹出現節點q,右子樹出現p,那么該節點就是節點p和q的最近公共祖先。

所以遞歸邏輯就是:如果遞歸遍歷遇到q,就返回q;遇到p,就返回p,那么如果左右子樹的返回值不為空,說明此時的中節點,一定是p和q的最近公共祖先。?

因為題目中說了二叉樹節點是不重復的,所以不用擔心會不會左子樹和右子樹都返回q或p這樣的問題。

實現代碼如下:

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {//遞歸if(root==null||root==p||root==q)return root;TreeNode left=lowestCommonAncestor(root.left,p,q);TreeNode right=lowestCommonAncestor(root.right,p,q);if(left!=null&&right!=null)return root;else if(left==null&&right!=null)return right;else if(left!=null&&right==null)return left;else return null;}
}

如果left 和 right都不為空,說明此時root就是最近公共節點。這個比較好理解。

如果left為空,right不為空,就返回right,說明目標節點是通過right返回的,反之亦然

為什么left為空,right不為空,目標節點就通過right返回?

我們來看下面的圖:

節點為10的左子樹返回null,右子樹返回7,那么此時節點10就要把右子樹的返回值返回上去。

完整流程圖如下:

?

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

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

相關文章

自增主鍵為什么不是連續的?

前言 如果一個線程回滾&#xff0c;例如唯一鍵沖突的情況回滾時&#xff0c;回滾了sql語句&#xff0c;但是并沒有把自增的值也-1。那么就會導致下一條插入的數據自增id出現了跳躍。 自增主鍵為什么不是連續的&#xff1f;前言執行時機為什么自增主鍵不是連續的為什么不回滾自…

OpenCV圖像基本操作:讀取、顯示與保存

在圖像處理項目中&#xff0c;圖像的 讀取&#xff08;imread&#xff09;、顯示&#xff08;imshow&#xff09; 和 保存&#xff08;imwrite&#xff09; 是最基礎也是最常用的三個操作。本文將詳細介紹這三個函數的功能、用法和注意事項&#xff0c;并提供一個完整示例供讀者…

.NET控制臺應用程序中防止程序立即退出

在VB.NET控制臺應用程序中防止程序立即退出&#xff0c;主要有以下幾種常用方法&#xff0c;根據需求選擇適合的方案&#xff1a; 方法1&#xff1a;等待用戶輸入&#xff08;推薦&#xff09; Module Module1Sub Main()Console.WriteLine("程序開始運行...") 這里是…

Vue3 + Three.js 極速入門:打造你的第一個3D可視化項目

文章目錄前言一、環境準備1.1 創建Vue3項目1.2 安裝Three.js二、Three.js核心概念速覽三、實戰&#xff1a;創建旋轉立方體3.1 組件化初始化四、核心代碼解析4.1 Vue3響應式整合技巧4.2 性能優化要點五、進階功能擴展5.1 數據驅動控制5.2 加載3D模型六、常見問題解決七、資源推…

【設計模式】享元模式(輕量級模式) 單純享元模式和復合享元模式

享元模式&#xff08;Flyweight Pattern&#xff09;詳解一、享元模式簡介 享元模式&#xff08;Flyweight Pattern&#xff09; 是一種 結構型設計模式&#xff08;對象結構型模式&#xff09;&#xff0c;它通過共享技術實現相同或相似對象的重用&#xff0c;以減少內存占用和…

驅動開發_2.字符設備驅動

目錄1. 什么是字符設備2. 設備號2.1 設備號概念2.2 通過設備號dev分別獲取主、次設備號的宏函數2.3 主設備號的申請靜態申請動態分配2.4 注銷設備號3. 字符設備3.1 注冊字符設備3.2 注銷字符設備3.3 應用程序和驅動程序的關系3.4 file_opertaions結構體3.5 class_create3.6 創建…

直播推流技術底層邏輯詳解與私有化實現方案-以rmtp rtc hls為例-優雅草卓伊凡

直播推流技術底層邏輯詳解與私有化實現方案-以rmtp rtc hls為例-優雅草卓伊凡由于我們的甲方客戶要開始為我們項目產品上加入私有化的直播&#xff0c;這塊不得不又撿起來曾經我們做直播推流的事情了&#xff0c;其實私有化直播一直并不是一件容易的事情&#xff0c;現在大部分…

一文讀懂現代卷積神經網絡—深度卷積神經網絡(AlexNet)

目錄 深度卷積神經網絡&#xff08;AlexNet&#xff09;是什么&#xff1f; 一、AlexNet 的核心創新 1. 深度架構 2. ReLU 激活函數 3. 數據增強 4. Dropout 正則化 5. GPU 并行計算 6. 局部響應歸一化&#xff08;LRN&#xff09; 二、AlexNet 的網絡結構 三、AlexN…

JVM 垃圾收集算法全面解析

1. 引言1.1 為什么需要垃圾收集&#xff1f;在Java應用中&#xff0c;垃圾收集&#xff08;Garbage Collection&#xff0c;GC&#xff09;是一個至關重要的機制&#xff0c;它使得開發者不需要手動管理內存。與傳統的語言&#xff08;如C或C&#xff09;不同&#xff0c;Java通…

Vmware中安裝的CentOS7如何擴展硬盤大小

起初創建虛擬機時&#xff0c;大小設置不合理&#xff0c;導致我在嘗試開源項目時空間不足重新擴展硬盤&#xff0c;不僅需要在虛擬機設置中配置&#xff0c;還需要在系統內重新進行分區一、虛擬機設置打開虛擬機設置→硬盤→擴展&#xff0c;將大小設置為自己期望的大小&#…

Python+MongoDB高效開發組合

如大家所知&#xff0c;Python與MongoDB的結合是一種高效的開發組合&#xff0c;主要用于通過Python進行數據存儲、查詢及管理&#xff0c;利用MongoDB的文檔型數據庫特性實現靈活的數據處理。下面讓 Python 連接上 MongoDB&#xff1a;安裝 PyMongo&#xff1a;pip3 install p…

【論文閱讀】Masked Autoencoders Are Effective Tokenizers for Diffusion Models

introduce什么樣的 latent 空間更適合用于擴散模型&#xff1f;作者發現&#xff1a;相比傳統的 VAE&#xff0c;結構良好、判別性強的 latent 空間才是 diffusion 成功的關鍵。研究動機&#xff1a;什么才是“好的 latent 表征”&#xff1f;背景&#xff1a;Diffusion Models…

每日一SQL 【游戲玩法分析 IV】

文章目錄問題案例執行順序使用分組解決問題 案例 執行順序 SQL 語句的執行順序&#xff08;核心步驟&#xff09; 同一層級的select查詢內部, 別名在整個 SELECT 計算完成前不生效 使用分組解決 select distinct s.product_id, Product.product_name from Sales sleft join …

內部文件審計:企業文件服務器審計對網絡安全提升有哪些幫助?

企業文件服務器審計工作不僅對提升企業網絡信息安全起到重要作用&#xff0c;還能對企業內部網絡文件信息是否合規進行判斷。因此企業文件服務器審計一直被高度重視。 一、文件服務器為何成為攻擊焦點&#xff1f; 企業文件服務器通常集中存儲財務報表、人事檔案、研發資料、客…

FusionOne HCI 23 超融合實施手冊(超聚變超融合)

產品介紹 FusionOne HCI作為實現企業信息一體化的IT基礎設施平臺&#xff0c;以“軟硬件垂直深度集成和調優”、“快速部署”、“統一管理”的理念&#xff0c;提供應用融合部署&#xff0c;提升核心業務運作效率&#xff0c;降低整體采購成本。 FusionOne HCI代表了IT產品的…

AI算姻緣測算小工具流量主微信小程序開源

功能特點 響應式設計&#xff1a;完美適配各種移動設備屏幕尺寸 精美UI界面&#xff1a; 柔和的粉紅色漸變背景 圓角卡片設計 精心設計的字體和間距 愛心圖標點綴 動態效果&#xff1a; 點擊按鈕時的動畫反饋 測算結果的平滑過渡動畫 愛心漂浮動畫 進度條動態填充 AI測算功能&a…

Vue獲取上傳Excel文件內容并展示在表格中

一、安裝依賴 npm install xlsx 二、引用依賴 import XLSX from xlsx 三、代碼實現 1、注意&#xff1a;函數 analysis 中reader.readAsBinaryString(file)&#xff0c;file的數據格式如圖所示 2、示例代碼 <!-- 項目使用的前端框架為非流行框架&#xff0c;主要關注…

pipelineJob和pipeline的關系

pipelineJob與pipeline在Jenkins體系中構成配置層與執行層的協同關系,具體關聯如下: 一、核心功能定位 概念作用實現層級pipelineJob定義Job的元數據(如SCM配置、日志策略)配置層pipeline描述實際構建流程(如階段劃分、并行任務)執行層scriptPath橋梁作用:將配置層定義…

第二十篇 Word文檔自動化:Python批量生成、模板填充與內容修改,告別繁瑣排版!

python實現word 自動化重復性文檔制作&#xff0c;手動填充模板&#xff0c;效率低下還易錯1.python-docx入門&#xff1a;Word文檔的“瑞士軍刀”&#xff01;1.1 安裝與基礎概念&#xff1a;文檔、段落、運行、表格1.2 打開/創建Word文檔&#xff1a;Python與Word的初次接觸1…

【C# in .NET】7. 探秘結構體:值類型的典型代表

探秘結構體&#xff1a;值類型的典型代表 在 C# 的類型系統中&#xff0c;結構體&#xff08;Struct&#xff09;作為值類型的典型代表&#xff0c;一直扮演著既基礎又微妙的角色。許多開發者在日常編碼中雖頻繁使用結構體&#xff08;如int、DateTime等&#xff09;&#xff0…