翻转二叉树,对称二叉树,二叉树的最大深度,二叉树的最小深度

后序遍历:只有后序遍历才能将左右孩子的信息返回给根节点;需要收集孩子信息向上一层节点返回的都是后序遍历

1.翻转二叉树

在这里插入图片描述

前序后序可以,中序不行
在这里插入图片描述
在这里插入图片描述
!](https://img-blog.csdnimg.cn/1e0526a7bcc048c1876a7b56e6c99072.png)
在这里插入图片描述

其中红色代表当前处理的节点,在遍历时,处理动作为加入到result集合中,在翻转中,处理动作为swap(node.left, node.right)

代码如下:(非递归)

public TreeNode invertTree(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    if(root != null) stack.push(root);

    while(stack.size() > 0){
        TreeNode node = stack.peek();
        if(node != null){
            node = stack.pop();
            //根右左
            stack.push(node);
            stack.push(null);
            if(node.right != null) stack.push(node.right);
            if(node.left != null) stack.push(node.left);
        }
        else{
            stack.pop();
            node = stack.pop();
            swap(node.left, node.right, node);
        }
    }

    return root;
}

void swap(TreeNode n1, TreeNode n2, TreeNode root){
    root.left = n2;
    root.right = n1;
}

代码如下:(递归版)

public TreeNode invertTree(TreeNode root) {
    dfs(root);
    return root;
}

void dfs(TreeNode root){
    if(root == null) return;
    
    dfs(root.left);
    dfs(root.right);
    swap(root.left, root.right, root);
}

void swap(TreeNode n1, TreeNode n2, TreeNode root){
    root.left = n2;
    root.right = n1;
}
2.对称二叉树

后序遍历:只有后序遍历才能将左右孩子的信息返回给根节点;需要收集孩子信息向上一层节点返回的都是后序遍历

关键: 判断根节点的左右孩子是否可以相互翻转

public boolean isSymmetric(TreeNode root) {
    if(root == null) return false;
    return compare(root.left, root.right);
}

public boolean compare(TreeNode n1, TreeNode n2){
    //停止条件
    if(n1 == null && n2 == null) return true;
    if(n1 == null || n2 == null) return false;
    if(n1.val != n2.val) return false;

    //对于n1和n2来说,n1:左右根;n2:右左根  都是后序遍历
    boolean b1 = compare(n1.left, n2.right);
    boolean b2 = compare(n1.right, n2.left);
    boolean b3 = b1 && b2; //根
    return b3;
}

左子树遍历:左右根;右子树遍历:右左根;都是后序遍历。
因为你不可能不遍历左右孩子就知道根节点是不是对称的

3.二叉树的高度与深度
  • 高度:任意节点到叶子节点的距离
  • 深度:任意节点到根节点的距离
  • 求高度用后序遍历 (自底向上),求深度用前序遍历 (自顶向下)
4.二叉树的最大深度

前序遍历:

int res = 0;
public int maxDepth(TreeNode root) {
    DD(root, 0);
    return res;
}

public void DD(TreeNode node, int cur){
    if(node == null){
        res = Math.max(res, cur);
        return;
    }
    
	//cur++;                  //根            
    DD(node.left, cur+1);     //左
    DD(node.right, cur+1);    //右
}

转化为求二叉树的最大高度:即根节点的高度(后序遍历)

public int maxDepth(TreeNode root) {
    if(root == null) return 0;

    int ll = maxDepth(root.left);   //左
    int rr = maxDepth(root.right);  //右
    return Math.max(ll, rr)+1;      //根
}
5.二叉树的最小深度

最小深度是从根节点到最近叶子节点的最短路径上的节点数量

前序遍历:

int res = 0x3f3f3f3f;
public int minDepth(TreeNode root) {
    if(root == null) return 0;
    DD(root, 1);
    return res;
}

public void DD(TreeNode node, int cur){
	//停止条件:叶子节点
    if(node.left == null && node.right == null){
        res = Math.min(res, cur);
        return;
    }
	
	//cur++;                                        //根
    if(node.left != null) DD(node.left, cur+1);     //左
    if(node.right != null) DD(node.right, cur+1);   //右

}

层序遍历

public int minDepth(TreeNode root) {
    int res = 0;
    Deque<TreeNode> dq = new ArrayDeque<>();
    if(root != null) dq.addLast(root);

    while(!dq.isEmpty()){
        res++;
        int size = dq.size();

        while(size-- > 0){
            TreeNode node = dq.pollFirst();
            if(node.left == null && node.right == null) return res;
            if(node.left != null) dq.addLast(node.left);
            if(node.right != null) dq.addLast(node.right);
        }
    }

    return res;
}

后序遍历:转化为求叶子节点的最小高度

public int minDepth(TreeNode root){
    if(root == null) return 0;
    if(root.left == null && root.right == null) return 1;
    
    int ll = 0x3f3f3f3f;
    int rr = 0x3f3f3f3f;
    if(root.left != null) ll = minDepth(root.left);   //左
    if(root.right != null) rr = minDepth(root.right); //右
    int gg = Math.min(ll, rr)+1;                      //根
    return gg;
}

加一个root.left == null && root.right == null的返回条件,是因为最小深度的定义是到叶子节点的节点数,如果不加,遇到left为null而right不为null的node,会认为这个node的高度为1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值