树-常见的题解

Posted hequnwang10

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树-常见的题解相关的知识,希望对你有一定的参考价值。

对树的操作主要有递归,DFS,BFS。

104. 二叉树的最大深度

递归

当前节点不为空,则遍历左右子树。

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public int maxDepth(TreeNode root) 
        if(root == null)
            return 0;
        
        //递归
        return 1+Math.max(maxDepth(root.left),maxDepth(root.right));
    

BFS

将每一层的节点保存至链表中,然后将每一层的节点出表,将下层的节点入表,一层一层的遍历。

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public int maxDepth(TreeNode root) 
        if(root == null)
            return 0;
        
        //BFS
        Deque<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        int cnt = 0;
        while(!queue.isEmpty())
            int size = queue.size();
            cnt++;
            for(int i = 0;i<size;i++)
                TreeNode node = queue.poll();
                if(node.left!= null)
                    queue.add(node.left);
                
                if(node.right != null)
                    queue.add(node.right);
                
            
        
        return cnt;
    

110. 平衡二叉树


递归

当前节点不为空,则遍历左右子树。判断当前节点是否为平衡树,在继续判断左右自己点是否为平衡树。

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public boolean isBalanced(TreeNode root) 
        if(root == null)
            return true;
        
        return Math.abs(height(root.left)-height(root.right))<=1 && isBalanced(root.left) && isBalanced(root.right);
    
    //定义一个函数,用于计算树的高度
    public int height(TreeNode root)

        if(root == null)
            return 0;
        
        return 1+Math.max(height(root.left),height(root.right));
    

时间复杂度 O(N^2);

自底向上递归

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    boolean res = true;
    public boolean isBalanced(TreeNode root) 
        height(root);
        return res;
    
    //定义一个函数,用于计算树的高度,自底向上递归
    public int height(TreeNode root)
        if(root == null)
            return 0;
        
        //判断左右子树的高度差
        int left = height(root.left);
        int right = height(root.right);
        if(Math.abs(left-right)>1)
            res = false;
        
        return 1+Math.max(left,right);
    

110. 平衡二叉树


计算树的路径长度的最大值,计算当前节点的左右子树的深度,左右深度的和就是构成一条路径,去最大值,这题使用自底向上的递归

自底向上递归

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    int max = 0;
    public int diameterOfBinaryTree(TreeNode root) 
        depth(root);
        return max;
        
    
    //自底向上的递归 计算树的深度
    public int depth(TreeNode root)
        if(root == null)
            return 0;
        
        //计算左子树的深度
        int left = depth(root.left);
        //System.out.println("root:"+root.val+"left:" + left);
        //计算右子树的深度
        int right = depth(root.right);
        //System.out.println("root:"+root.val+"right:" + right);
        //更新直径,当前节点的最长路径为左右子树的两个深度之和,然后取最大值
        max = Math.max(max,left+right);
        //System.out.println("max:"+max);
        return Math.max(left,right)+1; 
    

root:4left:0
root:4right:0
max:0
root:2left:1
root:5left:0
root:5right:0
max:0
root:2right:1
max:2
root:1left:2
root:3left:0
root:3right:0
max:2
root:1right:1
max:3

110. 平衡二叉树

自底向上递归

定义根节点的左右节点,然后递归实现将左右子树交换

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public TreeNode invertTree(TreeNode root) 
		if(root == null)
            return null;
        
        //将左右子树互换
        TreeNode left = root.left;
        // if(left != null)
        //     System.out.println("root:"+root.val+"left:" + left.val);
        // 
        
        TreeNode right = root.right;
        // if(right != null)
        //     System.out.println("root:"+root.val+"right:" + right.val);
        // 

        //递归执行
        root.left = invertTree(right);
        // if(root.left != null)
        //     System.out.println("root:"+root.val+"left:" + root.left.val);
        // 
        
        root.right = invertTree(left);
        // if(root.right != null)
        //     System.out.println("root:"+root.val+"right:" + root.right.val);
        // 
        return root;
    

root:4left:2
root:4right:7
root:7left:6
root:7right:9
root:7left:9
root:7right:6
root:4left:7
root:2left:1
root:2right:3
root:2left:3
root:2right:1
root:4right:2

自上而下的递归

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public TreeNode invertTree(TreeNode root) 
        if(root == null)
            return null;
        
        //将左右子树互换
        TreeNode left = root.left;
        root.left = root.right;
        root.right = left;       
        
        //递归执行
        invertTree(root.left);        
        invertTree(root.right);
        
        return root;
    

617. 合并二叉树

自上而下的递归

创建一个新的节点,将树1和树2的对应的值相加赋值给当前节点,递归实现。

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) 
        //递归实现
        if(t1 == null && t2 == null)
            return null;
        
        if (t1 == null) 
            return t2;
        
        if (t2 == null) 
            return t1;
        
        TreeNode node = new TreeNode(t1.val+t2.val);
        node.left = mergeTrees(t1.left,t2.left);
        node.right = mergeTrees(t1.right,t2.right);
        return node;
    

BFS

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) 
        //BFS
        if(t1 == null && t2 == null)
            return null;
        
        if (t1 == null) 
            return t2;
        
        if (t2 == null) 
            return t1;
        
        TreeNode node = new TreeNode(t1.val+t2.val);
        Deque<TreeNode> queue = new LinkedList<>();
        Deque<TreeNode> queue1 = new LinkedList<>();
        Deque<TreeNode> queue2 = new LinkedList<>();
        queue.add(node);
        queue1.add(t1);
        queue2.add(t2);
        while(!queue1.isEmpty() && !queue2.isEmpty())
            TreeNode root = queue.poll(), node1 = queue1.poll(), node2 = queue2.poll();
            TreeNode left1 = node1.left, left2 = node2.left, right1 = node1.right, right2 = node2.right;
            if(left1 != null || left2 != null)
                //分为三种情况,都不为空 或者有一个为空
                if(left1 != null && left2 != null)
                    TreeNode left = new TreeNode(left1.val+left2.val);
                    root.left = left;
                    queue1.add(left1);
                    queue2.add(left2);
                    queue.add(left);
                else if(left1 != null)
                    root.left = left1;
                else if(left2 != null)
                    root.left = left2;
                
            

            if (right1 != null || right2 != null) 
                if (right1 != null && right2 != null) 
                    TreeNode right = new TreeNode(right1.val + right2.val);
                    root.right = right;
                    queue.add(right);
                    queue1.add(right1);
                    queue2.add(right2);
                 else if (right1 != null) 
                    root.right = right1;
                 else if(right2 != null)
                    root.right = right2;
                
            
        
        return node;
    

112. 路径总和


递归实现

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public boolean hasPathSum(TreeNode root, int targetSum) 
        //根节点到叶子节点
        //递归实现
        if(root == null)
            return false;
        
        //判断是否为叶子节点
        if(root.left == null && root.right == null)
            //如果存在总和路径
            if(targetSum == root.val)
                return true;
            else
                return false;
            
        

        return hasPathSum(root.left,targetSum-root.val) || hasPathSum(root.right,targetSum-root.val);
    

广度优先搜索

使用两个队列,其中一个保存节点,另一个保存节点值相加和,若最后为叶子节点时,并且当前节点的和为target,返回true。

class Solution 
    public boolean hasPathSum(TreeNode root, int targetSum) 
        //根节点到叶子节点
        if(root == null)
            return false;
        
        //BFS
        //使用两个队列保存节点和节点的值
        Deque<TreeNode> node = new LinkedList<>();
        Deque<Integer> value = new LinkedList<>();
        node.add(root);
        value.add(root.val);
        while(!node.isEmpty())
            TreeNode curNode = node.poll();
            int sum = value.poll();
            if(curNode.left == null && curNode.right == null)
                if(targetSum == sum)
                    return true;
                
                continue;
            
            if(curNode.left != null)
                node.add(curNode.left);
                value.add(sum+curNode.left.val);
            
            if(curNode.right != null)
                node.add(curNode.right);
                value.add(sum+curNode.right.val);
            
        
        return false;
    

572. 另一棵树的子树

递归实现

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 
    public boolean isSubtree(TreeNode root, TreeNode subRoot) 
        //递归思想
        if(root == null)
            return false;
        
        return isSubtreeWithRoot(root,subRoot) || isSubtree(root.left,subRoot) || isSubtree(root.right,subRoot);

    
    //判断当前节点与子树是否相等
    public boolean isSubtreeWithRoot(TreeNode root, TreeNode subRoot)
        //终止条件
        if(root == null && subRoot == null)
            return true;
        
        if(root == null || subRoot == null)
            return false;
        
        if(root.val != subRoot.val)
            以上是关于树-常见的题解的主要内容,如果未能解决你的问题,请参考以下文章

二叉树常见的算法题

[洛谷P3384]模板树链剖分

#树#遍历#leetCode404.左子树之和

考试9.5

洛谷3384:模板树链剖分——题解

Abandoned country HDU - 5723