## 題解 ### Brute force ```python=! # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: if not root: return 0 return self.countNodes(root.left) + self.countNodes(root.right) + 1 ``` ### Binary Search + Bit Manipulation #### 1. 找出 Tree 有幾層 只要一直遍歷左子樹到底就可以算出樹的層數 ### 2. 使用二進位定位節點路徑 1. 先找出要找節點的 level ,套入公式 node = 1 << (level - 1) 2. 使用 node & target 得到 0 或 1,0 代表 left,1 代表 right 3. 每次 node 比較完 target 都要向右移一位 node >>= 1 4. 直到 node == 0 時停止尋找節點 5. 如果節點存在,則會在 node == 0 時走到節點上,判斷指針是否為 null 即可 ![](https://i.imgur.com/Y5bAYXK.jpg) #### 3. 進行二分查找定位最大位置 如果樹的層數 為 3 我們可以知道節點: 最小總數為 2 ** (3-1) = 4 最大總數為 2 ** (3 + 1) - 1 = 7 所以我們要查找的範圍就會是在 4 - 7 之間,找出最大並且已存在的節點,這樣子時間複雜度就可以降低到 avg. O(logn) ```python=! # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def countNodes(self, root: Optional[TreeNode]) -> int: def find_height(root): output = 0 while root.left: output += 1 root = root.left return output def binary_search(root,height): low = (1 << height) high = (1 << (height + 1)) - 1 while low < high: mid = low + (high - low + 1) // 2 # 要 +1 if find(root,mid,height): low = mid else: high = mid - 1 return low def find(root,target,height): current_node = 1 << (height - 1) node = root while node and current_node > 0: if (current_node & target) == 0: node = node.left else: node = node.right current_node = current_node >> 1 return node is not None if not root: return 0 height = find_height(root) return binary_search(root,height) ```