代码随想录算法训练营Day15
完全二叉树结点的数量
- 后序遍历套模板,时间复杂度为O(n)
class Solution {
public int countNodes(TreeNode root) {
if(root == null){
return 0;
}
int l = countNodes(root.left);
int r = countNodes(root.right);
int result = l+r+1;
return result;
}
}
- 根据完全二叉树的特点简化上述代码,如果一侧是满二叉树,直接用2^深度-1算得满子树的节点数(如何判断是满二叉树?向左遍历得到的深度和向右遍历得到的深度相等)
class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
TreeNode left = root.left;
TreeNode right = root.right;
int ldepth = 1;
int rdepth = 1;
while (left != null) {
left = left.left;
ldepth++;
}
while (right != null) {
right = right.right;
rdepth++;
}
if (ldepth == rdepth) {
return (int) Math.pow(2, ldepth) - 1;//满二叉树的公式
}
int ld = countNodes(root.left);
int rd = countNodes(root.right);
return ld + rd + 1;
}
}
平衡二叉树
最大高度的应用,注意跳出递归的条件
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null){
return true;
}
if(Math.abs(depth(root.left)-depth(root.right))>1){
return false;
}
boolean l = isBalanced(root.left);
boolean r = isBalanced(root.right);
return l&&r;
}
public int depth(TreeNode root){
if(root == null){
return 0;
}
int ld = depth(root.left);
int rd = depth(root.right);
return Math.max(ld,rd)+1; //这里混了,求最大高度不是求节点数量!
}
}
二叉树的所有路径
回溯的思想,在遍历完左子树之后,将左子节点弹出,再遍历右子节点
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
if (root == null) {
return res;
}
List<Integer> paths = new ArrayList<>();
traversal(root, paths, res);
return res;
}
private void traversal(TreeNode root, List<Integer> paths, List<String> res) {
paths.add(root.val);//前序遍历
// 遇到叶子结点,递归结束
if (root.left == null && root.right == null) {
// 输出
StringBuilder sb = new StringBuilder();
for (int i = 0; i < paths.size() - 1; i++) {//加->的
sb.append(paths.get(i)).append("->");
}
sb.append(paths.get(paths.size() - 1));//不加->的
res.add(sb.toString());//添加进结果列表
return;
}
// 递归和回溯
if (root.left != null) { // 左
traversal(root.left, paths, res);
paths.remove(paths.size() - 1);// 回溯
}
if (root.right != null) { // 右
traversal(root.right, paths, res);
paths.remove(paths.size() - 1);// 回溯
}
}
}
所有左叶子结点的和
下面代码求得是所有叶子结点的和
class Solution {
public int sumOfLeaves(TreeNode root) {
if (root == null) {
return 0;
} else if (root.left == null && root.right == null) {
return root.val; // 当前节点是叶子节点,返回其值
}
// 递归计算左右子树的叶子节点和
int l = sumOfLeaves(root.left);
int r = sumOfLeaves(root.right);
return l + r;
}
}
下面代码是求所有左叶子结点的和
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if(root == null){
return 0;
}
int l = sumOfLeftLeaves(root.left);
int r = sumOfLeftLeaves(root.right);
int mid = 0;
if(root.left != null && root.left.right == null && root.left.left == null){
mid = root.left.val;
}
return l+r+mid;
}
}

浙公网安备 33010602011771号