[leetcode #222] Count Complete Tree Nodes
3506 ワード
Problem
Given the root of a complete binary tree, return the number of the nodes in the tree.
According to Wikipedia, every level, except possibly the last, is completely filled in a complete binary tree, 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.
Design an algorithm that runs in less than O(n) time complexity.
Example 1:
Input: root = [1,2,3,4,5,6]
Output: 6
Example 2:Input: root = []
Output: 0
Example 3:Input: root = [1]
Output: 1
Constraints:・ The number of nodes in the tree is in the range [0, 5 * 10⁴].
・ 0 <= Node.val <= 5 * 10⁴
・ The tree is guaranteed to be complete.
Idea
これは完全ツリーのノード数を計算する問題です.ツリー内を簡単にナビゲートしてノード数を計算するだけで問題を簡単に解くことができるが,完全なツリーであるため平均時間複雑度はO(n)より低い.完了ツリーでは、ナビゲーション時に左側のサブノードのみのノードを検索するか、兄弟ノードが見つかりますが、深さが異なるノードを見つけたときにすぐにノードの数を取得できます.すなわち、サブノードをブラウズする際に、そのノードに指定された数字で個数を取得することができる.
このように解くと結果はいいと思いますが、実際には1ミリ秒かけて他の人がどのように解いたのかを確定しました.
0ミリ秒の解を生成するには、次のようにします.ノードを参照するたびに、左側のサブツリーの深さと右側のサブツリーの深さを比較します.2つの深さが同じ場合、左側のサブツリーはfull treeであるため、右側のサブツリーをナビゲートし、左側のサブツリーの深さを左にシフトした値をノード数に追加します.depthが異なる場合、右側のサブツリーはフルツリーであるため、左側のサブツリーをナビゲートし、右側のサブツリーのdepthが右に移動した値をノード数に追加します.このプロセスを繰り返すと,ノードの個数を容易に求めることができる.
Solution
class Solution {
public int countNodes(TreeNode root) {
if (root == null)
return 0;
return traverseTree(root, 0, 0, 1);
}
private int traverseTree(TreeNode node, int depth, int maxDepth, int num) {
if (depth > maxDepth)
maxDepth = depth;
if (node.left == null && node.right == null) {
if (maxDepth != depth)
return 2 * num - 1;
else
return num;
}
if (node.left != null & node.right == null)
return 2 * num;
int left = traverseTree(node.left, depth+1, maxDepth, num*2);
int right = traverseTree(node.right, depth+1, maxDepth, num*2+1);
return Math.max(left, right);
}
}
上のコードは私が作ったコードで、下のようにもっといいです.class Solution {
public int countNodes(TreeNode root) {
// Base case
if(root == null) return 0;
// Get the leftDepth of left subtree and right subtree to check which one is unfull tree
int left = leftDepth(root.left);
int right = leftDepth(root.right);
if(left == right) {
// Left subtree is a full tree, and right subtree could be a non-full tree
return (1 << left) + countNodes(root.right);
} else {
// Right subtree is a full tree, and left subtree could be a non-full tree
return countNodes(root.left) + (1 << right);
}
}
private int leftDepth(TreeNode root) {
int ans = 0;
while(root != null) {
ans++;
root = root.left;
}
return ans;
}
}
Reference
https://leetcode.com/problems/count-complete-tree-nodes/
Reference
この問題について([leetcode #222] Count Complete Tree Nodes), 我々は、より多くの情報をここで見つけました https://velog.io/@timevoyage/leetcode-222-Count-Complete-Tree-Nodesテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol