leetcode刷題(6):二叉樹的使用

文章目錄

    • 104. 二叉樹的最大深度
      • 解題思路
      • c++ 實現
    • 94. 二叉樹的中序遍歷
      • 解題思路
      • c++ 實現
    • 101. 對稱二叉樹
      • 解題思路
      • c++ 實現
    • 96. 不同的二叉搜索樹
      • 解題思路
      • c++ 實現
    • 102. 二叉樹的層序遍歷
      • 解題思路
      • c++ 實現

104. 二叉樹的最大深度

題目: 給定一個二叉樹 root ,返回其最大深度。

二叉樹的 最大深度 是指從根節點到最遠葉子節點的最長路徑上的節點數。

示例:
在這里插入圖片描述

解題思路

  • 沒有左右子節點的節點,稱為葉子節點
node->left ==nullptr && node->right ==nullptr`
  • 葉子節點所在的層數,就是從跟節點到葉子節點的距離
  • 統計遍歷所有節點,找到葉子節點
    • 如果當前節點不是葉子節點,則判斷該節點左節點或右節點是否葉子節點
    • 記錄每個葉子節點,所在層數,找到最遠距離的葉子節點

c++ 實現

class Solution {
public:int ans =0;void dfs(TreeNode* root, int level){if (root ==nullptr) return;if(root->left==nullptr && root->right==nullptr){ans = max(ans,level);}dfs(root->left,level+1);dfs(root->right,level+1);}int maxDepth(TreeNode* root) {dfs(root,1);return ans;}
};
  • 定義dfs函數,傳入節點以及所在的層level; 因為當前節點所在的層等于跟節點到該節點的距離,可以用level來表示距離
  • 首先從跟節點root開始遍歷,對應的level為1;
  • 如果到達葉子節點,則更新最遠距離ans
  • 然后接著從root->left開始,以及root->right開始尋找葉子節點,當前節點所在層為level+1
  • 最終遍歷完所有節點,找到最遠距離ans

94. 二叉樹的中序遍歷

題目: 給定一個二叉樹的根節點 root ,返回 它的 中序 遍歷
示例:
在這里插入圖片描述

解題思路

  • 中序遍歷: left -> root ->right(左中右)
  • 遞歸遍歷,首先考慮dfs

c++ 實現

class Solution {
public:vector<int> ans;void dfs(TreeNode* root){if (root==nullptr) return;dfs(root->left);ans.push_back(root->val);dfs(root->right);}vector<int> inorderTraversal(TreeNode* root) {dfs(root);return ans;}
};
  • 完整c++ 調試代碼
#include <iostream>
#include <vector>
using namespace std;struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x):val(x),left(nullptr),right(nullptr) {};
};class Solution {
public:vector<int> inorderTraversal(TreeNode* root){vector<int> result;inorder(root,result);return result;}
private:void inorder(TreeNode* root, vector<int>& result){if (root == nullptr) return;inorder(root->left,result);result.push_back(root->val);inorder(root->right,result);}
};int main()
{// 示例二叉樹: 1 /   \ 2     3// 創建二叉樹TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);// 使用中序遍歷函數Solution solution;vector<int> inorderTraversalResult = solution.inorderTraversal(root);// 打印結果for (int val:inorderTraversalResult){cout << val << " ";}// 清理內存delete root->left;delete root->right;delete root;return 0;
}

101. 對稱二叉樹

題目: 給你一個二叉樹的根節點 root , 檢查它是否軸對稱。
示例:
在這里插入圖片描述

解題思路


觀察對稱二叉樹,查找滿足對稱的條件,可以發現

  • 對稱樹,它的子節左右對稱,因此子節點需相同(如圖紅色的2和2)
  • 同時,子節點的孫子節點,左右兩側也要滿足對稱,即 left_tree->left = right_tree->right; left_tree->right = right_tree->left;
  • 找到規律后,遞歸遍歷二叉樹,判斷二叉樹是否對稱。

參考:https://www.cnblogs.com/itdef/p/14400148.html

c++ 實現

class Solution {
public:bool dfs(TreeNode* l,TreeNode* r){//遍歷到最后,都沒有找到不相等的節點,那么就是對稱的if(l==nullptr && r==nullptr) return true;if(l==nullptr && r !=nullptr) return false;if(l!=nullptr && r==nullptr) return false;if(l->val !=r->val) return false;// if(l->val ==r->val) return true; // 如果加了這一句,則這棵樹遍歷到存在左右節點相同,就不繼續向下遍歷了,因此不要加return dfs(l->left,r->right) && dfs(l->right,r->left); }bool isSymmetric(TreeNode* root) {return dfs(root->left,root->right);}
};
  • 如果遍歷過程中,左右存在任意不相等的,則直接判斷不是對稱樹
  • 如果遍歷到最后,都沒有發現不相等。因為已經到樹的最后,此時 l->leftr->right都為空,而且l->right和l->left也都是空, 根據if(l==nullptr && r==nullptr) return true;此時dfs(l->left,r->right) && dfs(l->right,r->left)返回true
  • 注意不要加:if(l->val ==r->val) return true, 不然遍歷不到樹的最后,只要在中間節點存在滿足這一要求的,就停止判斷了,無法對整棵樹進行判斷。

96. 不同的二叉搜索樹

題目: 給你一個整數 n ,求恰由 n 個節點組成且節點值從 1 到 n 互不相同的 二叉搜索樹 有多少種?``返回滿足題意的二叉搜索樹的種數
示例:
在這里插入圖片描述

解題思路

二叉搜索樹, 也稱二叉排序樹二叉查找樹。具有下列性質的二叉樹:

  • 若它的左子樹不空,則左子樹上所有結點的值均小于它的根結點的值
  • 若它的右子樹不空,則右子樹上所有結點的值均大于它的根結點的值
  • 它的左、右子樹也分別為二叉排序樹。
  • 二叉搜索樹作為一種經典的數據結構,它既有鏈表的快速插入與刪除操作的特點,又有數組快速查找的優勢
  • 使用動態規劃dp的方法求解, 設dp[n]記錄n個連續節點(從 1 到 n 互不相同)組成的二叉搜索樹的種類。
  • 二叉搜索樹,左子樹上的所有節點均小于它的跟節點,右子樹上的所有節點均大于它的跟節點
  • 可知dp[1]1, 因為只有一個節點,排列的可能就只有一種;另外dp[0]也為1,因為也只有一種排列可能。dp[2] 可組成兩種不同的搜索二叉樹,因此dp[2]=2
    在這里插入圖片描述
  • 對于3個節點,列出了所有的不同的搜索二叉樹, 總共有5種
    • 如果1作為根節點,由于找不到比跟節點小的數作為左子樹,因為左子樹為空(dp[0]), 此時2,3兩個節點在右子樹上存在2種搜索二叉樹的可能,也就是dp[2]:如果2在右子樹上,那么3由于比2大,那么3只能是它的右子節點。如果3在右子樹上,由于2比3小,2只能是它的左子節點); 此時種類數為: dp[0] * dp[2] = 2
      在這里插入圖片描述
    • 如果2作為跟節點, 因為1比跟節點2小1只能是它的左節點,由于3比2大3只能是根節點2的右節點, 因此只有1種可能:因此種類計算為 dp[1]*dp[1] =1
    • 如果3作為跟節點,由于沒有比它大的數,所以右子樹為空,也就是dp[0],剩下的兩個數字都在左子樹上,對應為dp[2]: 如果1作為跟節點3的左節點,那么剩下的2只能是1的右節點(2比1大);如果2作為跟節點3的左子節點,那么剩下的1只能是2的左子節點(1比2小)。因此種類計算為 dp[2]*dp[0] =2
    • 所以對于3個節點來說,所有的二叉樹為: dp[0] * dp[2] + dp[1]*dp[1] + dp[2]*dp[0] =5

因此得出如下規律:

  • (1)遍歷每個數,作為根節點
  • (2) 計算該跟節點下,所有搜索二叉樹的種類左子樹(種類)* 右字數(種類)
  • (3) 最后將計算結果求和

c++ 實現

class Solution {
public:int numTrees(int n) {int dp[20]; memset(dp,0x0,sizeof(dp));dp[0] =1;dp[1] =1;// 遍歷p[i]for(int i=2;i<=n;i++){   // i個節點,元素值 <=i; 遍歷以每個節點作為跟節點for (int j=1;j<=i;j++){dp[i] += dp[j-1] * dp[i-j];}}return dp[n];}
};
  • 首先初始化dp[20] , 并通過memset 置為0 ,因為n<=19, 初始化的大小足夠了。
  • 其中:dp[0] 和dp[1] 都為1
  • 通過遍歷 for(int i=2;i<=n;i++)來計算p[i]的值
  • 對于i個節點,元素值 <=i; 遍歷以每個節點作為跟節點, 計算此時搜索二叉樹的種類
dp[j-1] * dp[i-j]
  • 因為左節點元素小于根節點,所以為dp[j-1], 根據解題思路的總結,右節點對應為dp[i-j] , 因為j-1+i-j =i-1;

102. 二叉樹的層序遍歷

題目:給你二叉樹的根節點 root ,返回其節點值的 層序遍歷 。 (即逐層地,從左到右訪問所有節點)。

示例:
在這里插入圖片描述

解題思路

BFS 廣度優先搜索算法的介紹,看出博文: BFS和DFS優先搜索算法

  • BFS遍歷二叉樹 ,添加了遍歷的樹的層級level
  • 根據層級決定新開vector或者直接push

在這里插入圖片描述

  • 先將跟節點root層級0,加入到隊列queue中,然后遍歷隊列
  • 首先彈出根節點,并拿到節點值存儲到ans中
  • 根節點下一層子節點加入隊列
  • 然后繼續彈出隊列中的節點,如果節點層級大于curr節點,增需要重新開一個vector,存儲該節點的值,如果和當前層級是一樣的,則直接push_back到vector中。
  • 然后pop該節點,并將該節點的下一層子節點添加隊
  • 繼續上述步驟,直到全部遍歷完。。。。

c++ 實現

class Solution {
public:vector<vector<int>> ans;int curr =0;       // current levelvector<int> v;     // 單個level 保存的結果void bfs(TreeNode* root){if(root==nullptr) return;//創建用來存儲節點和level的queuequeue<pair<TreeNode*,int>> q;// 放入第一個節點,同時記錄節點的層級q.push({root,0});while(!q.empty()){// 循環彈出需要處理的節點TreeNode* p=q.front().first;int level = q.front().second;// 記得從隊列中pop掉q.pop();// 如果處理的節點層級比當前vector層級更大// 那么說明上一層的節點數據已經處理完畢,需要重新開一個vector來記錄新的層級節點if(level>curr){// 更新curr 層級curr = level;// 將已經處理完畢的層級數據vector, 添加到ans結果中ans.push_back(v);// 得到一個空的vector, 用于記錄新的層級數據v.clear();v.push_back(p->val);}else{//如果處理節點的層級和當前curr層級一樣,直接push_back即可v.push_back(p->val);}// 將當前處理的節點的子節點,放入隊列中,注意要加上子節點所在的層級if (p->left !=nullptr) q.push({p->left,level+1});if (p->right !=nullptr) q.push({p->right,level+1});}// 記得將最后一次的結果v,加入ans中ans.push_back(v);return;}vector<vector<int>> levelOrder(TreeNode* root) {bfs(root);return ans;}
};
  • 首先創建一個隊列queue來節點及所在level, 并插入根節點
//創建用來存儲節點和level的queue
queue<pair<TreeNode*,int>> q;
// 放入第一個節點,同時記錄節點的層級
q.push({root,0});
  • 遍歷隊列,循環彈出需要處理的節點
// 循環彈出需要處理的節點TreeNode* p=q.front().first;int level = q.front().second;// 記得從隊列中pop掉q.pop();
  • 如果處理的節點層級比當前vector層級更大,那么說明上一層的節點數據已經處理完畢,需要重新開一個vector記錄新的層級節點
if(level>curr){// 更新curr 層級curr = level;// 將已經處理完畢的層級數據vector, 添加到ans結果中ans.push_back(v);// 得到一個空的vector, 用于記錄新的層級數據v.clear();v.push_back(p->val);}
  • 如果處理節點的層級和當前curr層級一樣,直接push_back即可
 else{//如果處理節點的層級和當前curr層級一樣,直接push_back即可v.push_back(p->val);}
  • 然后將pop掉的當前節點p的(下一層級)子節點加入隊列queue, 同時它的level+1
if (p->left !=nullptr) q.push({p->left,level+1});
if (p->right !=nullptr) q.push({p->right,level+1});
  • 隊列遍歷完,記得將最后一次結果v加入到ans中
        // 記得將最后一次的結果,加入ans中ans.push_back(v);

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

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

相關文章

重新認識Flutter跨平臺技術(上)

背景 2017年,Flutter剛推出來的時候,正好自己在做TV Launcher開發的工作。 我們知道TV Launcher是Android TV操作系統中的一個啟動器應用程序。它負責在打開電視時展示給用戶的主要界面,包括應用程序圖標、推薦內容等。通過Android TV Launcher,用戶可以方便地瀏覽和啟動…

ALV 圖標顯示

前言 在ABAP ALV中&#xff0c;使用fieldcat來定義列表中每個字段的顯示屬性&#xff0c;包括圖標&#xff08;Icon&#xff09;的顯示。圖標可以在ALV列表中為特定列的行或標題添加圖形元素&#xff0c;以增強視覺提示或傳達附加信息。 ICON查詢 圖標的名稱用事務碼”ICON“進…

智能BI(后端)-- 系統異步化

文章目錄 系統問題分析什么是異步化&#xff1f;業務流程分析標準異步化的業務流程系統業務流程 線程池為什么需要線程池&#xff1f;線程池兩種實現方式線程池的參數線程池的開發 項目異步化改造 系統問題分析 問題場景&#xff1a;調用的服務能力有限&#xff0c;或者接口的…

離岸公司+外貿

為什么外貿公司老板都喜歡注冊離岸公司呢&#xff1f;怎樣利用離岸公司做進出口貿易呢&#xff1f; 今天大家花一分鐘時間來了解清楚 第一步就是注冊一家離岸公司&#xff0c;將這個離岸公司作為國際外貿的中轉站&#xff0c;與國外客戶簽訂單&#xff0c;你從國內工廠采購商…

【文檔理解】TextMonkey:一種OCR-Free的用于文檔理解的多模態大模型

背景 傳統的信息提取&#xff0c;通常是從文本中提取信息&#xff0c;相關技術也比較成熟。然而對于復雜領域&#xff0c;例如圖片&#xff0c;文檔等形式的數據&#xff0c;想要提取出高質量的、可信的數據難度就比較大了&#xff0c;這種任務也常稱為&#xff1a;視覺文檔理…

CTF網絡安全大賽web題目:just_sqli

這道題目是bugku的web題目 題目的 描  述: KosenCTF{} 原文鏈接&#xff1a; CTF網絡安全大賽web題目&#xff1a;just_sqli - 紅客網-網絡安全與滲透技術 題目Web源代碼&#xff1a; <?php$user NULL; $is_admin 0;if (isset($_GET["source"])) {highlig…

齊護K210系列教程(二十七)_語音識別

語音識別 1.燒錄固件和模型2.語音識別程序2.1訓練并識別2.2使用本地文件語音識別 3.課程資源聯系我們 1.燒錄固件和模型 注&#xff1a;本應用只適用于有麥克風功能的型號&#xff1a;AIstart_pro、AIstart_掌機、AIstart_Mini, 其它型號不支持&#xff01; 機器碼生成以及模…

linux中遠程服務器上傳輸文件的10個sftp命令示例

目錄 1. 如何連接到 SFTP 2. 幫助 3.檢查當前工作目錄 4. 使用 sftp 列出文件 遠程 本地 5. 使用 sftp 上傳文件 6. 使用 sftp 上傳多個文件 7. 使用 sftp 下載文件 8. 在 sftp 中切換目錄 遠程 本地 9. 使用 sftp 創建目錄 10. 使用 sftp 刪除目錄 11. 退出 sf…

(001)apidoc 的安裝

安裝 1.確定 node 和 npm 的匹配版本 node -vv10.14.1# 切換node 版本 nvm list nvm use 20.12.22.安裝 apidoc。 npm install -g apidoc3.生成文檔&#xff1a; apidoc -i ../ -o document/ -f ".java$"-i &#xff1a;指定掃描路徑。-o&#xff1a;輸出目錄。…

golang并發(同步)多任務高性能執行聚合

taskgroup golang并發執行多任務&#xff0c;并聚合多任務結果。 使用文檔、 項目github 使用: go get github.com/mlee-msl/taskgroup 功能特點 并發安全的執行多個任務將多個任務的結果進行聚合通過扇出/扇入模式&#xff0c;結合線程安全channel實現高效協程間通信多任務復…

【Linux:環境變量】

環境變量一般是指在操作系統中用來指定操作系統環境的一些參數 常見的環境變量&#xff1a; PATH 指定可執行程序的搜索路徑 系統級的文件&#xff1a;/etc/bashrc 用戶級文件&#xff1a;~/.bashrc ~/.bash_profile HOME 指定用戶的主要工作目錄&#xff08;當前用…

kettle從入門到精通 第六十一課 ETL之kettle 任務調度器,輕松使用xxl-job調用kettle中的job和trans

想真正學習或者提升自己的ETL領域知識的朋友歡迎進群&#xff0c;一起學習&#xff0c;共同進步。若二維碼失效&#xff0c;公眾號后臺加我微信入群&#xff0c;備注kettle。 1、大家都知道kettle設計的job流程文件有個缺點&#xff1a;只能設置簡單的定時任務&#xff0c;無法…

DPDK:用rte_wmb()來保序,對ARM和IA而言,RTE_WMB()的實現有何不同

rte_wmb()函數在DPDK中用于實現寫入屏障&#xff08;Write Memory Barrier&#xff09;&#xff0c;它的作用是確保在CPU執行寫操作之前&#xff0c;所有先前的寫操作已經被完全刷新到內存中。這個函數在IA和ARM處理器上的實現有一些不同。 對于Intel Architecture (IA)處理器而…

PHP黑魔法之既是0又是1/switch/$a==0可用.繞過(非數字都可繞過)/PHP://偽協議繞過

1、既是0又是1的情況 $a==1 & $test[$a]=t 時 知識點1)php在處理數字時,如果數字的位數超過 16 位是可以弱等于1的,也就是 var_dump( 9999999999999999999 == 1 );//true 因為當數字位數超過 16 位時,是將該數字轉換成了數值為 1 的字符串進行處理 知識點2)在科學…

LabVIEW和usrp連接實現ofdm通信系統 如何實現

1. 硬件準備 USRP設備&#xff1a;選擇合適的USRP硬件&#xff08;如USRP B210或N210&#xff09;&#xff0c;并確保其與計算機連接&#xff08;通常通過USB或以太網&#xff09;。天線&#xff1a;根據頻段需求選擇合適的天線。 2. 軟件安裝 LabVIEW&#xff1a;安裝LabVI…

【Golang】 Golang 的 GORM 庫中的 Rows 函數

文章目錄 前言一、Rows 函數解釋二、代碼實現三、總結 前言 在使用 Go 語言進行數據庫操作時&#xff0c;GORM&#xff08;Go Object-Relational Mapping&#xff09;庫是一個常用的工具。它提供了一種簡潔和強大的方式來處理數據庫操作。本文將介紹 GORM 庫中的 Rows 函數&am…

數據庫-索引(高級篇)

文章目錄 索引概念&#xff1f;索引演示&#xff1f;索引的優劣&#xff1f;為什么使用索引就快&#xff1f;本篇小結 更多相關內容可查看 索引概念&#xff1f; 索引&#xff08;index&#xff09;是幫助MySQL高效獲取數據的數據結構(有序)。在數據之外&#xff0c;數據庫系統…

生成完美口型同步的 AI 數字人視頻

目錄 摘要 關鍵詞 1 前言 1.1 研究背景 1.2 研究意義 2 技術框架 2.1 深度學習框架 2.2 語音識別 2.3 面部動作捕捉和口型同步 2.4 綜合項目 3 實現過程 3.1 環境搭建 3.2 代碼開發 3.3 整合代碼 3.4 部署 3.5 更多細節 4 測試過程 4.1 數據準備 4.2 面部檢測…

語法分析-文法

如果對于一部文法中&#xff0c;存在至少一個句子有兩個或者兩個以上的語法樹則該文法是二義性的。 我們可以以上面的例子進行解釋&#xff0c;對于第棵個語法樹&#xff0c;我們可以看到是先進行了加法運算再進行的乘法運算&#xff0c;因為需要先把EE作為整體運算完后再成為E…

上海亞商投顧:滬指低開低走 兩市成交額跌破8000億

上海亞商投顧前言&#xff1a;無懼大盤漲跌&#xff0c;解密龍虎榜資金&#xff0c;跟蹤一線游資和機構資金動向&#xff0c;識別短期熱點和強勢個股。 一.市場情緒 市場全天震蕩走低&#xff0c;三大股指尾盤均跌近1%。地產股逆勢走強&#xff0c;光大嘉寶、天地源、云南城投…