leetcode222 完全二叉樹的節點個數

完全二叉樹?的定義如下:在完全二叉樹中,除了最底層節點可能沒填滿外,其余每層節點數都達到最大值,并且最下面一層的節點都集中在該層最左邊的若干位置。若最底層為第?h?層(從第 0 層開始),則該層包含?1~?2h?個節點。

方法一:直接使用普適的求二叉樹節點個數解法

遞歸:

 class Solution {
public:int countNodes(TreeNode* root) {if(root == nullptr) return 0;int leftnum = countNodes(root->left);int rightnum = countNodes(root->right);int num = leftnum + rightnum + 1;return num;}
};

迭代:

class Solution {
public:int countNodes(TreeNode* root) {if(root == nullptr) return 0;queue<TreeNode*> q;q.push(root);int num = 0;while(!q.empty()){int size = q.size();for(int i = 0; i < size; i++){TreeNode* cur = q.front();q.pop();num++;if(cur->left) q.push(cur->left);if(cur->right) q.push(cur->right);}}return num;}
};

方法二:利用二叉樹性質(更高效)

在完全二叉樹中,除了最底層節點可能沒填滿外,其余每層節點數都達到最大值,并且最下面一層的節點都集中在該層最左邊的若干位置。若最底層為第 h 層,則該層包含 1~?2^(h-1) ?個節點。

完全二叉樹只有兩種情況,情況一:就是滿二叉樹,情況二:最后一層葉子節點沒有滿。

對于情況一,可以直接用 2^樹深度 - 1 來計算,注意這里根節點深度為1。

對于情況二,分別遞歸左孩子,和右孩子,遞歸到某一深度一定會有左孩子或者右孩子為滿二叉樹,然后依然可以按照情況1來計算。

可以看出如果整個樹不是滿二叉樹,就遞歸其左右孩子,直到遇到滿二叉樹為止,用公式計算這個子樹(滿二叉樹)的節點數量。

這里關鍵在于如何去判斷一個左子樹或者右子樹是不是滿二叉樹呢?

在完全二叉樹中,如果遞歸向左遍歷的深度等于遞歸向右遍歷的深度,那說明就是滿二叉樹。

class Solution {
public:int countNodes(TreeNode* root) {if(root == nullptr) return 0;TreeNode* left = root;TreeNode* right = root;int leftheight = 0, rightheight = 0;while(left){leftheight++;left = left->left;}while(right){rightheight++;right = right->right;}if(leftheight == rightheight)  return (1 << leftheight) - 1;return 1 + countNodes(root->left) + countNodes(root->right);}
};

在代碼?return (1 << leftheight) - 1;?中,1 << leftheight?是一個位運算表達式,表示計算?2的leftheight次冪。

1的二進制00000001

比如左移一位變為00000010就是2

左移2位變為00000100就是4

故就可以表示2的leftheight次方。

方法三:二分法

  1. 計算樹的深度?d?完全二叉樹的深度由最左路徑決定,d 是最后一層的高度(從 0 開始計數)。

    • 一直向左遍歷,直到葉子節點,統計深度。

    • 例如,[1,2,3,4,5,6]?的深度?d = 2(從?1 → 2 → 4,共 3 層,但?d?是最后一層的高度,這里需根據實現調整)。

  2. 二分查找最后一層的節點數

    • 最后一層的節點編號為?1?到?2^d(例如?d=2?時編號?1~4)。

    • 通過二分法檢查某個編號的節點是否存在:

      • 如果存在,向右搜索(說明右側可能還有更多節點)。

      • 如果不存在,向左搜索(說明該節點及右側不存在)。

  3. 計算總節點數

    • 前?d?層是滿二叉樹,節點數為?2^d - 1

    • 最后一層的節點數為二分找到的最后一個存在的編號?left

    • 總節點數 = (2^d - 1) + left

class Solution {
private:int getdepth(TreeNode* root){int depth = 0;while(root->left){depth++;root = root->left;}return depth;}bool exist(TreeNode* root, int d, int idx){int left = 0, right = (1 << d) - 1;for(int i = 0; i < d; ++i){int mid = left + (right - left) / 2;if(idx <= mid){root = root->left;right = mid;}if(idx > mid){root = root->right;left = mid + 1;}}return root != nullptr;}public:int countNodes(TreeNode* root) {if (!root) return 0;int d = getdepth(root); if (d == 0) return 1;int left = 1, right = (1 << d);while (left < right) {int mid = left + (right - left) / 2;if (exist(root, d, mid)) {left = mid + 1;} else {right = mid;}}return (1 << d) - 1 + left;}
};
  • exists?函數的任務:給定一個編號?idx,判斷它在完全二叉樹的最后一層是否存在。

  • 如何判斷

    1. 從根節點出發,按照?idx?的二進制位決定路徑(0=左,1=右)。

    2. 走完?d?步后,檢查最終到達的節點是否為空:

      • 如果?node != nullptr,說明該節點存在。

      • 如果?node == nullptr,說明該節點不存在。

if (exists(root, d, mid))
  • 含義:檢查編號為?mid?的節點是否存在。

  • 如果存在 (true)

    • 說明?mid?及所有比它小的節點都存在。

    • 我們需要嘗試更大的編號,因此調整左邊界:

    • 邏輯:既然?mid?存在,最后一個存在的節點可能在?[mid + 1, right]?范圍內。

  • 如果不存在 (false)

    • 說明?mid?節點缺失,且所有比它大的節點也一定缺失(因為完全二叉樹的最后一層從左到右連續排列)。

    • 我們需要嘗試更小的編號,因此調整右邊界

    • 邏輯:最后一個存在的節點可能在?[left, mid - 1]?范圍內。

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

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

相關文章

若依集成BladeX單點登錄的令牌管理與api請求流程

目錄 概述系統架構單點登錄流程令牌管理機制接口調用流程關鍵代碼實現數據結構安全性考慮常見問題與解決 概述 本文檔詳細說明若依系統如何實現與BladeX的單點登錄集成&#xff0c;包括令牌管理和接口調用的完整流程。整個集成采用基于OAuth2的授權碼流程&#xff0c;允許用…

《AI大模型應知應會100篇》第27篇:模型溫度參數調節:控制創造性與確定性

第27篇&#xff1a;模型溫度參數調節&#xff1a;控制創造性與確定性 摘要 在大語言模型的使用中&#xff0c;“溫度”&#xff08;Temperature&#xff09;是一個關鍵參數&#xff0c;它決定了模型輸出的創造性和確定性之間的平衡。通過調整溫度參數&#xff0c;您可以根據任…

愛普生SG2520VGN差分晶振5G基站的時鐘解決方案

在 5G 通信時代&#xff0c;數據流量呈爆發式增長&#xff0c;5G 基站作為信號的核心中轉樞紐&#xff0c;承載著前所未有的數據傳輸與處理重任。從海量的物聯網設備連接&#xff0c;到高速移動用戶的數據交互&#xff0c;每一個環節都對基站的性能提出了嚴苛要求。而精準穩定的…

GitHub SSH連接終極解決方案

GitHub SSH連接終極解決方案&#xff1a;443端口修改多場景故障排查指南 一、問題現象速查 當開發者執行以下命令時出現連接異常&#xff1a; ssh -T gitgithub.com常見報錯類型&#xff1a; 經典端口阻塞ssh: connect to host github.com port 22: Connection refused密鑰驗…

面向新一代擴展現實(XR)應用的物聯網框架

中文標題&#xff1a; 面向新一代擴展現實&#xff08;XR&#xff09;應用的物聯網框架 英文標題&#xff1a; Towards an IoT Framework for the New Generation of XR Applications 作者信息 Joo A. Dias&#xff0c;UNIDCOM - IADE&#xff0c;歐洲大學&#xff0c;里斯本&…

Qt unknown module(s) in qt:serialport解決方法

在Ubuntu和CentOS系統中,若使用Qt時遇到Unknown module(s) in QT: serialport錯誤,通常是由于未正確安裝Qt的串口模塊(QSerialPort)或項目配置不當導致。以下是針對兩種系統的解決方案: 一、安裝Qt串口模塊 1. Ubuntu/Debian系列 安裝開發包: 執行以下命令安裝Qt5串口模…

閥門軸承電動車工件一鍵精修軟件

若需定制開發“ComfyUI意見精修軟件” 技術棧建議&#xff1a; 前端&#xff1a;React/Vue Figma插件API&#xff08;直接讀取設計稿&#xff09;。 后端&#xff1a;Node.js/Python NLP庫&#xff08;spaCy/NLTK&#xff09;。 數據庫&#xff1a;MongoDB&#xff08;存儲…

chapter32_SpringMVC與DispatcherServlet

一、簡介 從本章節開始進入SpringMVC的學習&#xff0c;SpringMVC最重要的類就是DispatcherServlet DispatcherServlet的本質是一個Servlet&#xff0c;回顧一下Servlet JavaWeb就是基于Servlet的Servlet接口有5個方法Servlet實現類是HttpServlet&#xff0c;自定義的Servle…

《Learning Langchain》閱讀筆記3-基于 Gemini 的 Langchain如何從LLMs中獲取特定格式

純文本輸出是有用的&#xff0c;但在某些情況下&#xff0c;我們需要 LLM 生成結構化輸出&#xff0c;即以機器可讀格式&#xff08;如 JSON、XML 或 CSV&#xff09;或甚至以編程語言&#xff08;如 Python 或 JavaScript&#xff09;生成的輸出。當我們打算將該輸出傳遞給其他…

中間件--ClickHouse-12--案例-1-日志分析和監控

1、案例背景 一家互聯網公司需要實時分析其服務器日志、應用日志和用戶行為日志&#xff0c;以快速發現潛在問題并優化系統性能。 2、需求分析 目標&#xff1a;實時分析日志數據&#xff0c;快速發現問題并優化系統性能。數據來源&#xff1a; 服務器日志&#xff1a;如 Ng…

多道程序和多任務操作系統區別

多道程序 vs. 多道任務&#xff1a;對比分析 ? 共同點 方面共同特征核心機制都依賴于進程/任務切換執行需求實現多個程序或任務"并發"執行系統支持都需要操作系統的支持&#xff08;如調度算法、內存管理&#xff09;本質目標提高資源利用率&#xff08;CPU不空轉…

齊次坐標變換+Unity矩陣變換

矩陣變換 變換&#xff08;transform)&#xff1a;指的是我們把一些數據&#xff0c;如點&#xff0c;方向向量甚至是顏色&#xff0c;通過某種方式&#xff08;矩陣運算&#xff09;&#xff0c;進行轉換的過程。 變換類型 線性變換&#xff1a;保留矢量加和標量乘的計算 f(x)…

閑來無事,用HTML+CSS+JS打造一個84鍵機械鍵盤模擬器

今天閑來無聊&#xff0c;突發奇想要用前端技術模擬一個機械鍵盤。說干就干&#xff0c;花了點時間搞出來了這么一個有模有樣的84鍵機械鍵盤模擬器。來看看效果吧&#xff01; 升級版的模擬器 屏幕錄制 2025-04-18 155308 是不是挺像那么回事的&#xff1f;哈哈&#xff01; 它…

智慧城市:如同為城市裝上智能大腦,開啟智慧生活

智慧城市的概念隨著信息技術的飛速發展而逐漸興起&#xff0c;它通過集成物聯網、大數據、人工智能和數字孿生等先進技術&#xff0c;為城市管理和居民生活帶來了前所未有的智能化變革。本文將深入探討這些核心技術及其在智慧城市的典型應用場景&#xff0c;展示智慧城市如何提…

科技快訊 | 智譜開源最新GLM模型系列;“AI 洗頭店”現身廣州;ChatGPT上線圖庫功能

智譜開源最新GLM模型系列&#xff0c;啟用全球域名“Z.ai” 4月15日&#xff0c;智譜開源最新GLM模型系列&#xff0c;包括32B和9B尺寸&#xff0c;涵蓋基座、推理、沉思三類模型&#xff0c;全部遵循MIT開源許可協議。推理模型GLM-Z1-32B-0414實測推理速度達200 tokens/秒&…

第32講:衛星遙感與深度學習融合 —— 讓地球“讀懂”算法的語言

目錄 ?? 一、講講“遙感+深度學習”到底是干啥的? ? 能解決什么問題? ?? 二、基礎原理串講:深度學習如何“看懂”遙感圖? ?? 遙感圖像數據類型: ?? CNN的基本思路: ?? 三、實戰案例:用CNN對遙感圖像做地類分類 ?? 所需R包: ??? 步驟一:構建訓…

【多線程5】面試常考鎖知識點

文章目錄 悲觀/樂觀鎖掛起等待鎖/自旋鎖偏向鎖輕量級/重量級鎖鎖升級CASCAS引發的ABA問題解決方案 原子類 公平/不公平鎖可重入鎖ReentrantLock讀寫鎖 Callable接口 這里的“悲觀”“樂觀”“掛起等待”“自旋”“輕量級”“重量級”“公平”“非公平”“可重入”僅代表某個鎖的…

第三屆世界科學智能大賽新能源賽道:新能源發電功率預測-數據處理心得體會1

看懂數據 比賽數據說明&#xff1a; 文檔&#xff08;報名之后可以下載&#xff09;大小操作初賽測試集.zip94MB下載初賽訓練集.zip632MB下載output.zip145KB下載 任務和主題 AI新能源功率預報&#xff1a;根據歷史發電功率數據和對應時段多類別氣象預測數據&#xff0c;實…

【云馨AI-大模型】2025年4月第三周AI領域全景觀察:硬件革命、生態博弈與國產化突圍

一、硬件算力突破點燃多智能體時代 谷歌在4月12日Cloud Next大會發布第七代TPU Ironwood&#xff0c;單芯片算力達4614 TFLOPs&#xff0c;較前代內存提升6倍&#xff0c;專為AI推理場景優化。配合發布的Gemini 2.5 Flash模型通過"思考"功能實現成本優化&#xff0c…

第3章 垃圾收集器與內存分配策略《深入理解Java虛擬機:JVM高級特性與最佳實踐(第3版)》

第3章 垃圾收集器與內存分配策略 3.2 對象已死 Java世界中的所有對象實例&#xff0c;垃圾收集器進行回收前就是確定對象哪些是活著的&#xff0c;哪些已經死去。 3.2.1 引用計數算法 常見的回答是&#xff1a;給對象中添加一個引用計數器&#xff0c;有地方引用&#xff0…