1. 程式人生 > 其它 >0222.-完全二叉樹的節點個數

0222.-完全二叉樹的節點個數

給你一棵 完全二叉樹 的根節點 root ,求出該樹的節點個數。

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

示例 1:

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

輸入:root = []
輸出:0
示例 3:

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

提示:

樹中節點的數目範圍是[0, 5 * 104]
0 <= Node.val <= 5 * 104
題目資料保證輸入的樹是 完全二叉樹

進階:遍歷樹來統計節點是一種時間複雜度為 O(n) 的簡單解決方案。你可以設計一個更快的演算法嗎?

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/count-complete-tree-nodes

python

# 0222.完全二叉樹的節點個數
class Solution:
    # 遞迴法
    def countNodes(self, root: TreeNode) -> int:
        def getNodesNum(node):
            if not node:
                return 0
            leftNum = getNodesNum(node.left)
            rightNum = getNodesNum(node.right)
            nodesNum = leftNum + rightNum + 1
            return nodesNum
        return getNodesNum(root)

    # 迭代法-層序遍歷
    def countNodes1(self, root: TreeNode) -> int:
        from collections import deque
        queue = deque()
        if root:
            queue.append(root)
        nums = 0
        while queue:
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                nums += 1
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return nums

    # 遞迴法-完全二叉樹版本
    def countNodes2(self, root: TreeNode) -> int:
        if not root:
            return 0
        left = root.left
        right = root.right
        # 左右子樹高度初始化為0,
        leftHeight = 0
        rightHeight = 0
        # 左子樹深度
        while left:
            left = left.left
            leftHeight += 1
        # 右子樹深度
        while right:
            right = right.right
            rightHeight += 1
        if leftHeight == rightHeight:
            return (2 << leftHeight)-1 # 2<<1 = 2^2 = 4, 非空時,height=1
        return self.countNodes2(root.left) + self.countNodes2(root.right) + 1


golang

package binaryTree

import "container/list"

// 迭代遍歷
func countNodes1(root *TreeNode) int {
	if root == nil { // 空時返回
		return 0
	}
	nums := 1
	queue := list.New() // 佇列控制層序遍歷
	queue.PushBack(root)
	for queue.Len() > 0 {
		length := queue.Len()
		for i:=0;i<length;i++ { // 遍歷當層的節點
			node := queue.Remove(queue.Front()).(*TreeNode) // 當次節點
			nums++
			if node.Left != nil { // 節點的左節點入隊
				queue.PushBack(node.Left)
			}
			if node.Right != nil { // 節點的右節點入隊
				queue.PushBack(node.Right)
			}
		}
	}
	return nums
}

// 遞迴-一般二叉樹
func countNodes2(root *TreeNode) int {
	if root == nil {
		return 0
	}
	res := 1
	if root.Right != nil {
		res += countNodes2(root.Right)
	}
	if root.Left != nil {
		res += countNodes2(root.Left)
	}
	return res
}

// 遞迴-完全二叉樹
func countNodes3(root *TreeNode) int {
	if root == nil {
		return 0
	}
	leftH, rightH := 0, 0
	leftNode := root.Left
	rightNode := root.Right
	for leftNode != nil {
		leftNode = leftNode.Left
		leftH++
	}
	for rightNode != nil {
		rightNode = rightNode.Right
		rightH++
	}
	if leftH == rightH {
		return (2 << leftH) - 1
	}
	return countNodes3(root.Left) + countNodes3(root.Right) + 1
}