文章目录
普通二叉树结点个数计算,时间复杂度O(n)
其实不需要是完全二叉树,可以是二叉树节点个数,就是一个二叉树遍历(不包括null节点),不知道为什么还是中等难度,解法包括:递归三遍历、迭代三遍历、层序遍历
最简单的方法(递归)
class Solution {
public int countNodes(TreeNode root) {
if(root == null) { // 防止下面的root.left root.right 空指针异常
return 0;
}
return 1+ countNodes(root.left) + countNodes(root.right); // 中左右 中每次加1,左子树遍历,右子树遍历
}
}
前序递归
class Solution {
List<Integer> list=new ArrayList<>(); // 返回值为list,但是参数中没有list,所以必须新建一个list盛放返回值
public int countNodes(TreeNode root) {
if (null == root) return list.size(); // null==root判断要在三个之前,防止空指针 return;返回一个完成标志就好了
list.add(root.val); // 中
countNodes(root.left); // 左
countNodes(root.right); // 右
return list.size();
}
}
中序递归
class Solution {
List<Integer> list=new ArrayList<>(); // 返回值为list,但是参数中没有list,所以必须新建一个list盛放返回值
public int countNodes(TreeNode root) {
if (null == root) return list.size(); // null==root判断要在三个之前,防止空指针 return;返回一个完成标志就好了
countNodes(root.left); // 左
list.add(root.val); // 中
countNodes(root.right); // 右
return list.size();
}
}
后序递归
class Solution {
List<Integer> list=new ArrayList<>(); // 返回值为list,但是参数中没有list,所以必须新建一个list盛放返回值
public int countNodes(TreeNode root) {
if (null == root) return list.size(); // null==root判断要在三个之前,防止空指针 return;返回一个完成标志就好了
countNodes(root.left); // 左
countNodes(root.right); // 右
list.add(root.val); // 中
return list.size();
}
}
前序迭代
class Solution {
public int countNodes(TreeNode root) {
if (null == root) return 0; // null==root判断要在三个之前,防止空指针 return;返回一个完成标志就好了
List<Integer> list=new ArrayList<>(); // 返回值为list,但是参数中没有list,所以必须新建一个list盛放返回值
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.peek(); //
if (node!=null){
stack.pop();
if (node.right !=null)stack.push(node.right); // 这一条if保证插入的不是一个null,后面取出node.val的时候不是空指针异常
if (node.left !=null) stack.push(node.left);
stack.push(node);stack.push(null);
}else{
stack.pop();
node = stack.pop();
list.add(node.val);
}
}
return list.size();
}
}
中序迭代
class Solution {
public int countNodes(TreeNode root) {
if (null == root) return 0; // null==root判断要在三个之前,防止空指针 return;返回一个完成标志就好了
List<Integer> list=new ArrayList<>(); // 返回值为list,但是参数中没有list,所以必须新建一个list盛放返回值
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.peek(); //
if (node!=null){
stack.pop();
if (node.right !=null)stack.push(node.right); // 这一条if保证插入的不是一个null,后面取出node.val的时候不是空指针异常
stack.push(node);stack.push(null);
if (node.left !=null) stack.push(node.left);
}else{
stack.pop();
node = stack.pop();
list.add(node.val);
}
}
return list.size();
}
}
后序迭代
class Solution {
public int countNodes(TreeNode root) {
if (null == root) return 0; // null==root判断要在三个之前,防止空指针 return;返回一个完成标志就好了
List<Integer> list=new ArrayList<>(); // 返回值为list,但是参数中没有list,所以必须新建一个list盛放返回值
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.peek(); //
if (node!=null){
stack.pop();
stack.push(node);stack.push(null);
if (node.right !=null)stack.push(node.right); // 这一条if保证插入的不是一个null,后面取出node.val的时候不是空指针异常
if (node.left !=null) stack.push(node.left);
}else{
stack.pop();
node = stack.pop();
list.add(node.val);
}
}
return list.size();
}
}
层序遍历
class Solution {
public int countNodes(TreeNode root) {
if (null == root) return 0; // null==root判断要在三个之前,防止空指针 return;返回一个完成标志就好了
List<Integer> list=new ArrayList<>(); // 返回值为list,但是参数中没有list,所以必须新建一个list盛放返回值
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size(); //
for (int i=0;i<size;i++){
TreeNode node = queue.poll();
list.add(node.val); // 层序遍历类似前序遍历,中左右
if (node.left!=null) queue.offer(node.left); // 这一条if保证插入的不是一个null,后面取出node.val的时候不是空指针异常
if (node.right!=null) queue.offer(node.right);
}
}
return list.size();
}
}
层序遍历类似前序遍历,中左右
利用完成二叉树的性质,时间复杂度O(logN)
二分查找 + 位运算
class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
int level = 0;
TreeNode node = root;
while (node.left != null) {
level++;
node = node.left;
}
int low = 1 << level, high = (1 << (level + 1)) - 1;
while (low < high) {
int mid = (high - low + 1) / 2 + low;
if (exists(root, level, mid)) {
low = mid;
} else {
high = mid - 1;
}
}
return low;
}
public boolean exists(TreeNode root, int level, int k) {
int bits = 1 << (level - 1);
TreeNode node = root;
while (node != null && bits > 0) {
if ((bits & k) == 0) {
node = node.left;
} else {
node = node.right;
}
bits >>= 1;
}
return node != null;
}
}