摘要:如果不等于,則是左子樹的節(jié)點數(shù),加上右子樹的節(jié)點數(shù),加上自身這一個。注意這里在左節(jié)點遞歸時代入了上次計算的左子樹最左深度減,右節(jié)點遞歸的時候代入了上次計算的右子樹最右深度減,可以避免重復(fù)計算這些深度做的冪時不要用,這樣會超時。
Count Complete Tree Nodes
遞歸樹高法 復(fù)雜度Given a complete binary tree, count the number of nodes.
Definition of a complete binary tree from Wikipedia: In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.
時間 O(N) 空間 O(1)
思路完全二叉樹的一個性質(zhì)是,如果左子樹最左邊的深度,等于右子樹最右邊的深度,說明這個二叉樹是滿的,即最后一層也是滿的,則以該節(jié)點為根的樹其節(jié)點一共有2^h-1個。如果不等于,則是左子樹的節(jié)點數(shù),加上右子樹的節(jié)點數(shù),加上自身這一個。
注意這里在左節(jié)點遞歸時代入了上次計算的左子樹最左深度減1,右節(jié)點遞歸的時候代入了上次計算的右子樹最右深度減1,可以避免重復(fù)計算這些深度
做2的冪時不要用Math.pow,這樣會超時。用1<
public class Solution { public int countNodes(TreeNode root) { return countNodes(root, -1, -1); } private int countNodes(TreeNode root, int lheight, int rheight){ // 如果沒有上輪計算好的左子樹深度,計算其深度 if(lheight == -1){ lheight = 0; TreeNode curr = root; while(curr != null){ lheight++; curr = curr.left; } } // 如果沒有上輪計算好的右子樹深度,計算其深度 if(rheight == -1){ rheight = 0; TreeNode curr = root; while(curr != null){ rheight++; curr = curr.right; } } // 如果兩個深度一樣,返回2^h-1 if(lheight == rheight) return (1 << lheight) - 1; // 否則返回左子樹右子樹節(jié)點和加1 return 1 + countNodes(root.left, lheight - 1, -1) + countNodes(root.right, -1, rheight - 1); } }迭代樹高法 復(fù)雜度
時間 O(N) 空間 O(1)
思路用迭代法的思路稍微有點不同,因為不再是遞歸中那樣的分治法,我們迭代只有一條正確的前進方向。所以,我們判斷的時左節(jié)點的最左邊的深度,和右節(jié)點的最左邊深度。因為最后一層結(jié)束的地方肯定在靠左的那側(cè),所以我們要找的就是這個結(jié)束點。如果兩個深度相同,說明左子樹和右子樹都是滿,結(jié)束點在右側(cè),如果右子樹算出的最左深度要小一點,說明結(jié)束點在左邊,右邊已經(jīng)是殘缺的了。根據(jù)這個大小關(guān)系,我們可以確定每一層的走向,最后找到結(jié)束點。另外,還要累加每一層的節(jié)點數(shù),最后如果找到結(jié)束點,如果結(jié)束點是左節(jié)點,就多加1個,如果結(jié)束點是右節(jié)點,就多加2個。
注意同樣的,記錄上次計算的最左深度,可以減少一些重復(fù)計算
用int記錄上次最左深度更快,用Integer則會超時
代碼未優(yōu)化版本
public class Solution { public int countNodes(TreeNode root) { int res = 0; Integer lheight = null, rheight = null; while(root != null){ // 得到左節(jié)點的最左深度 int leftH = getH(root.left); // 得到右節(jié)點的最左深度 int rightH = getH(root.right); // 左節(jié)點的最左深度大,說明右邊已經(jīng)殘缺,結(jié)束點在左邊 if(leftH > rightH){ if(rightH != 0) res += 1 << rightH; else return res + 2; root = root.left; // 否則說明結(jié)束點在右邊 } else { if(leftH != 0) res += 1 << leftH; else return res + 1; root = root.right; } } return res; } private int getH(TreeNode root){ int h = 0; while(root != null){ ++h; root = root.left; } return h; } } public class Solution { public int countNodes(TreeNode root) { int res = 0; int lheight = -1, rheight = -1; while(root != null){ // 如果沒有上次記錄的左邊最左深度,重新計算 if(lheight == -1){ TreeNode curr = root.left; lheight = 0; while(curr != null){ curr = curr.left; lheight++; } } // 如果沒有上次記錄的右邊最左深度,重新計算 if(rheight == -1){ TreeNode curr = root.right; rheight = 0; while(curr != null){ curr = curr.left; rheight++; } } // 深度相同,說明結(jié)束點在右邊 if(lheight == rheight){ // 如果是不是最后一個節(jié)點,累加這一層的節(jié)點 if(lheight != 0){ res += 1 << lheight; } else { // 如果是最后一個節(jié)點,結(jié)束點在右邊意味著右節(jié)點是缺失的,返回res+1 return res + 1; } root = root.right; lheight = rheight - 1; rheight = -1; // 否則結(jié)束點在左邊 } else { // 如果是不是最后一個節(jié)點,累加這一層的節(jié)點 if(rheight != 0){ res += 1 << rheight; } else{ // 如果是最后一個節(jié)點,返回res+2 return res + 2; } root = root.left; lheight = lheight - 1; rheight = -1; } } return res; } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/64647.html
摘要:題目要求計算一個完全二叉樹的節(jié)點個數(shù)。其中完全二叉樹是指除了最后一行,其余的每一行都必須是滿節(jié)點的樹。當然超時啦思路二講道理的遞歸思路一很明顯沒有充分利用這是一顆完全二叉樹的條件。 題目要求 Given a complete binary tree, count the number of nodes. Definition of a complete binary tree fro...
Problem Given a complete binary tree, count the number of nodes. Note: Definition of a complete binary tree from Wikipedia:In a complete binary tree every level, except possibly the last, is completel...
摘要:題目鏈接的題,用來做,這種求有多少的題一般都是。里多加一個信息表示以為的節(jié)點數(shù)。也可以做,因為是統(tǒng)計有多少的,其實就是求從最小值到的。的是,要做一個映射,把的值映射到之間。所以先把給一下,用一個來做映射。還有的方法,參考 315. Count of Smaller Numbers After Self 題目鏈接:https://leetcode.com/problems... divi...
摘要:如果我們從右往左看先序遍歷,就知道后兩個節(jié)點如果遇到第三個節(jié)點,則該節(jié)點就應(yīng)當是這兩個節(jié)點的父節(jié)點。如果在遍歷的過程中根節(jié)點數(shù)量小于,則說明這棵樹有問題。而如果遍歷結(jié)束之后,剩下的根節(jié)點數(shù)不等于,也說明這個先序遍歷存在問題。 題目要求 One way to serialize a binary tree is to use pre-order traversal. When we en...
閱讀 3006·2023-04-25 18:06
閱讀 2900·2021-11-22 09:34
閱讀 1801·2021-11-08 13:16
閱讀 1451·2021-09-24 09:47
閱讀 3135·2019-08-30 15:44
閱讀 2868·2019-08-29 17:24
閱讀 2694·2019-08-23 18:37
閱讀 2529·2019-08-23 16:55