二叉树的深度优先问题

33 阅读5分钟

二叉树的双指针

判断两颗树是否相同

相同的树

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p==null&&q==null){
            return true;
        }else if(p==null&&q!=null||p!=null&&q==null){
            return false;
        }
        LinkedList<TreeNode> queue1=new LinkedList<>();
        LinkedList<TreeNode> queue2=new LinkedList<>();
        queue1.offer(p);
        queue2.offer(q);
        while (!queue1.isEmpty()&&!queue2.isEmpty()){
            int size1 = queue1.size();
            int size2 = queue2.size();
            if(size1!=size2) return false;
            for (int i = 0; i < size1; i++) {
                TreeNode node1 = queue1.poll();
                TreeNode node2 = queue2.poll();
                if(node1.val!=node2.val) return false;
                if(node1.left!=null&&node2.left!=null){
                    queue1.offer(node1.left);
                    queue2.offer(node2.left);
                }else if(node1.left==null&&node2.left==null){

                }else {
                    return false;
                }
                if(node1.right!=null&&node2.right!=null){
                    queue1.offer(node1.right);
                    queue2.offer(node2.right);
                }else if(node1.right==null&&node2.right==null){

                }else {
                    return false;
                }
            }
        }
        return queue1.isEmpty()&&queue2.isEmpty()?true:false;


    }
}
class Solution1 {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p==null&&q==null) return true;
        if(p==null||q==null) return false;
        if(p.val!=q.val) return false;
        
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);


    }
}

对称二叉树

对称二叉树

class Solution {
     public boolean isSymmetric(TreeNode root) {
         if(root==null) return true;
         TreeNode left=root.left;
         TreeNode right=root.right;
         return isAlike( left,right);
    }

    private boolean isAlike(TreeNode left, TreeNode right) {
         if(left==null&&right==null) return true;
         if(right==null||left==null) return false;
         if(left.val!=right.val) return false;
         
         return isAlike(left.left,right.right)&&isAlike(left.right,right.left);
         
    }
}

合并二叉树

合并二叉树

class Solution {
    public static void main(String[] args) {
        TreeNode root1=new TreeNode(1);
        TreeNode root2=new TreeNode(1,new TreeNode(2),null);
        mergeTrees(root1,root2);
    }
    public static TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1==null&&root2==null) return null;
        if(root1==null||root2==null) {
            return root1==null?root2:root1;
        }
        TreeNode root=new TreeNode(root1.val+root2.val);
        TreeNode left=mergeTrees(root1.left,root2.left);
        TreeNode right=mergeTrees(root1.right,root2.right);
        root.left=left;
        root.right=right;
        return root;

    }
}

路径专题

二叉树的所有路径

二叉树的所有路径

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res=new ArrayList<>();
        StringBuilder sb=new StringBuilder();
        if(root==null) return res;
        addToRes(res,root,sb);
        return res;

    }

    private void addToRes(List<String> res, TreeNode root, StringBuilder sb) {
        if(sb.length()==0){
            sb.append(root.val);
        }else {
            sb.append("->"+root.val);
        }

        if(root.left==null&&root.right==null){
            res.add(sb.toString());
            return;
        }
        StringBuilder sbb=new StringBuilder(sb);
        if(root.left!=null) {
            addToRes(res,root.left,sbb);
        }
        sbb=new StringBuilder(sb);
        if(root.right!=null){
            addToRes(res,root.right,sbb);
        }
    }
}
class Solution {
    public static void main(String[] args) {
        TreeNode treeNode=new TreeNode(1,new TreeNode(2),null);
        binaryTreePaths(treeNode);
    }
    public static List<String> binaryTreePaths(TreeNode root) {
        List<String> res=new ArrayList<>();
        if(root==null) return res;
        addToRes(res,root,"");
        return res;

    }

    private static void addToRes(List<String> res, TreeNode root, String path) {
        if(root==null) return;
        if(root.left==null&&root.right==null) {
            res.add(path+root.val);
            return;
        }
        addToRes(res,root.left,path+root.val+"->");
        addToRes(res,root.right,path+root.val+"->");
    }
}

路径总和

路径总和

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        int sum=0;
        if(root==null) return false;
        return dp(root,sum,targetSum);

    }

    private boolean dp(TreeNode root, int sum, int targetSum) {
        if(root==null&&sum==targetSum) return true;
        if(root==null&&sum!=targetSum) return false;
        sum+=root.val;
        if(root.left!=null&&root.right!=null){
            return dp(root.left,sum,targetSum)||dp(root.right,sum,targetSum);
        }else if(root.right!=null){
            return dp(root.right,sum,targetSum);
        }else {
            return dp(root.left,sum,targetSum);
        }
       

    }
}

翻转的妙用

翻转二叉树

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        TreeNode left = invertTree(root.left);
        TreeNode right = invertTree(root.right);


        root.left = right;
        root.right = left;
        return root;

    }
}

最大深度问题

最大深度问题 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:

输入:root = [3,9,20,null,null,15,7] 输出:3

class Solution {
    public int maxDepth(TreeNode root) {
        if(root==null) return 0;
        return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
    }
}
class Solution1 {
    public int maxDepth(TreeNode root) {
        if(root==null) return 0;
        LinkedList<TreeNode> queue=new LinkedList<>();
        int dep=0;
        queue.offer(root);
        while (!queue.isEmpty()){
            dep++;
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if(node.right!=null) queue.offer(node.right);
                if(node.left!=null) queue.offer(node.left);
            }
        }
        return dep;
    }
}

判断平衡树

平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树_每个节点 _的左右两个子树的高度差的绝对值不超过 1 。

示例 1:

输入:root = [3,9,20,null,null,15,7] 输出:true

class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root==null) return true;
        int lenLeft= getDep(root.left);
        int lenRight= getDep(root.right);

        return Math.abs(lenLeft-lenRight)<=1&&isBalanced(root.right)&&isBalanced(root.left);

    }
    private int getDep(TreeNode root) {
        if(root==null) return 0;
        return Math.max(getDep(root.left),getDep(root.right))+1;
    }


}

:::info 解题思路 求节点的高度: 求出左右节点的高度:如果=-1就放回-1 如果左右高度差>1返回-1 结果不为-1就是平衡二叉树 :::

class Solution1 {
    public boolean isBalanced(TreeNode root) {
        int ans=getHeight(root);
        return ans==-1?false:true;
    }

    private int getHeight(TreeNode node) {
        if(node==null) return 0;
        int leftHeight = getHeight(node.left);
        if(leftHeight==-1) return -1;
        int rightHeight = getHeight(node.right);
        if(rightHeight==-1) return -1;
        return Math.abs(leftHeight-rightHeight)<=1?Math.max(leftHeight,rightHeight)+1:-1;

    }


}

最小深度

二叉树的最小深度 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 **说明:**叶子节点是指没有子节点的节点。

示例 1: 输入:root = [3,9,20,null,null,15,7] 输出:2

:::info 层序遍历: 压住队列中:如果队列中有元素没有子节点,说明就是最小深度 :::

class Solution1 {
    public int minDepth(TreeNode root) {
        if(root==null) return 0;
        LinkedList<TreeNode> queue=new LinkedList<>();
        int res=1;
        queue.offer(root);
        boolean flag=true;
        while (!queue.isEmpty()&&flag){
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if(node.left==null&&node.right==null) flag=false;
                if(node.left!=null) queue.offer(node.left);
                if(node.right!=null) queue.offer(node.right);
            }
            res++;
        }
        return res-1;

    }
}

:::info 递归 :::

class Solution {
    public int minDepth(TreeNode root) {
        if(root==null) return 0;
        if(root.left==null) return minDepth(root.right)+1;
        if(root.right==null) return minDepth(root.left)+1;
        return Math.min(minDepth(root.left),minDepth(root.right))+1;

    }


}

N叉树的最大深度

N叉树的最大深度 给定一个 N 叉树,找到其最大深度。 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。 N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

示例 1: 输入:root = [1,null,3,2,4,null,5,6] 输出:3

class Solution {
    public int maxDepth(Node root) {
        if(root==null) return 0;
        int max=0;
        for (Node child : root.children) {
            int dep = maxDepth(child);
            if(dep>max) max=dep;
        }
        return max+1;


    }
}

最近公共祖先问题

二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例 1: 输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出:3 解释:节点 5 和节点 1 的最近公共祖先是节点 3 。 示例 2: 输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出:5 解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

class Solution {

    public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null) return null;
        List<TreeNode> containP=new ArrayList<>();
        List<TreeNode> containQ=new ArrayList<>();
        List<TreeNode> list1 = getContainNodeList(containP, root, p);
        List<TreeNode> list2 = getContainNodeList(containQ, root, q);
        for (int i = list1.size()-1; i >=0; i--) {
            TreeNode treeNode = list1.get(i);
            if(list2.contains(treeNode)){
                return treeNode;
            }
        }
        return null;

        
    }

    private static List<TreeNode> getContainNodeList(List<TreeNode> list, TreeNode root, TreeNode node) {
        if(root==null) return list;
        list.add(root);
        List<TreeNode> listL=new ArrayList<>(list);

        if(root==node) return list;
        List<TreeNode> list1 = getContainNodeList(list, root.left, node);
        if(list1.contains(node)) return list1;
        List<TreeNode> list2 = getContainNodeList(listL, root.right, node);
        return list2;

    }


}
    public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null) return root;
        if(root==p||root==q) return root;
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);
        if(left!=null&&right!=null) return root;
        if(right==null&&left==null) return null;
        if(left==null) return right;
        if(right==null) return left;
        return null;

    }