美文网首页
LeetCode二叉树算法整理

LeetCode二叉树算法整理

作者: 高思阳 | 来源:发表于2018-10-18 13:46 被阅读11次

    1.LeetCode104 Maximum Depth of Binary Tree(求二叉树的最大深度)
    2.LeetCode111 Minimum Depth of Binary Tree(求二叉树的最小深度)
    3.LeetCode226 Invert Binary Tree(反转二叉树)
    4.等价二叉树(剑指Offer)
    5.对称的二叉树(剑指Offer)
    6.LeetCode404 Sum of Left Leaves(左叶子节点和)
    7.二叉树中和为某一值的路径(剑指Offer)
    8.树的子结构---判断B是不是A的子结构(剑指Offer)
    9.LeetCode110 Balanced Binary Tree(判断是不是平衡二叉树)
    10.求二叉树的最大宽度
    11.二叉树的前序遍历,中序遍历,后序遍历,层序遍历
    12.LeetCode257 Binary Tree Paths(二叉树的所有路径)

    1.LeetCode104 Maximum Depth of Binary Tree(求二叉树的最大深度)

    Given a binary tree, find its maximum depth.

    The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

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

    2.LeetCode111 Minimum Depth of Binary Tree(求二叉树的最小深度)

    Given a binary tree, find its minimum depth.

    The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

    也就是求根节点到最近叶子节点的距离。

    **
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public int minDepth(TreeNode root) {
            if(root==null) return 0;
            int left=minDepth(root.left);
            int right=minDepth(root.right);
            return (left==0||right==0)?left+right+1:Math.min(left,right)+1;    
      }
    }
    

    注意:二叉树的最小深度和最大深度不一样,要防止斜树出现

    3.LeetCode226 Invert Binary Tree(反转二叉树)

    Invert a binary tree.

       4
      /  \
      2     7
     /  \  /  \
    1  3 6  9

    to:

       4
      /  \
      7     2
     /  \  /  \
    9  6 3  1

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public TreeNode invertTree(TreeNode root) {
            if(root==null){
                return null;
            }
            TreeNode temp=root.left;
            root.left=root.right;
            root.right=temp;
            invertTree(root.left);
            invertTree(root.right);
            return root;
        }
    }
    

    4.等价二叉树(剑指Offer)

    检查两棵二叉树是否等价。等价的意思是说,首先两棵二叉树必须拥有相同的结构,并且每个对应位置上的节点上的数都相等。

    /** 
     * Definition of TreeNode: 
     * public class TreeNode { 
     *     public int val; 
     *     public TreeNode left, right; 
     *     public TreeNode(int val) { 
     *         this.val = val; 
     *         this.left = this.right = null; 
     *     } 
     * } 
     */  
     
    public class Solution {  
        /* 
         * @param a: the root of binary tree a. 
         * @param b: the root of binary tree b. 
         * @return: true if they are identical, or false. 
         */  
        public boolean isIdentical(TreeNode a, TreeNode b) {  
            // write your code here  
            if(a==null&&b==null)  return true;  
            if(a==null||b==null)  return false;  
            if(a.val==b.val) return isIdentical(a.left,b.left)&&isIdentical(a.right,b.right);  
            else  
            return false;  
        }  
    }  
    

    5.对称的二叉树(剑指Offer)

    请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

    /*
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
    
        public TreeNode(int val) {
            this.val = val;
        }
    }
    */
    public class Solution {
        boolean isSymmetrical(TreeNode pRoot)
        {
           return is(pRoot,pRoot);
        }
        
        boolean is(TreeNode t1,TreeNode t2){
            if(t1==null&&t2==null) return true;
            if(t1==null||t2==null) return false;                 //因为有上一个判断,这里说明t1 或 t2有一个为null
            if(t1.val==t2.val)
            return is(t1.left,t2.right)&&is(t1.right,t2.left);  //注意这里,左节点的左孩子应该和右节点的右孩子比
            else 
            return false;
        }
    }
    

    6.LeetCode404 Sum of Left Leaves(左叶子节点和)

    Find the sum of all left leaves in a given binary tree.

       3
      /  \
      9    20
        /  \
        15  7

    There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public int sumOfLeftLeaves(TreeNode root) {
            int sum=0;
            if(root==null)                  
                return 0;
            if(root.left!=null)
            {
                if((root.left.left==null)&&(root.left.right==null)){
                    sum=sum+root.left.val;
                }else
                sum=sum+sumOfLeftLeaves(root.left);
            }
            sum=sum+sumOfLeftLeaves(root.right);
            return sum;
        }
      }
    

    ①左节点不为空,先看左节点,左节点的左节点和右节点都是空,那么加左节点的val,否则继续递归求左节点
    ②之后再递归右节点,求得值。

    7.二叉树中和为某一值的路径(剑指Offer)

    输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

    import java.util.ArrayList;  
    /** 
    public class TreeNode { 
        int val = 0; 
        TreeNode left = null; 
        TreeNode right = null; 
     
        public TreeNode(int val) { 
            this.val = val; 
            } 
    */  
    public class Solution {  
        private ArrayList<Integer> child=new ArrayList<Integer>();  
        private ArrayList<ArrayList<Integer>> father=new ArrayList<ArrayList<Integer>>();  
        public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {  
            if(root==null)  
                return father;  
            child.add(root.val);  
            target-=root.val;                                  //通过一个节点就减去这个节点的值  
            if(target==0&&root.left==null&&root.right==null)   //关键1  如果是叶子结点且target已经减到0了  
                father.add(new ArrayList<Integer>(child));     //关键2  注意的是这种写法  
            FindPath(root.left,target);                          
            FindPath(root.right,target);                         
            child.remove(child.size()-1);   //关键3  
            return father;  
        }  
    }  
    

    最难理解的是

    child.remove(child.size()-1);   
    

    为什么这样搞呢?

    当我们递归完一个子树不满足条件,那么我们就会找这棵子树的父节点,然后看父节点的另一颗子树,所以要弹出已经压入的这个值。

    8.树的子结构---判断B是不是A的子结构(剑指Offer)

    输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

    /** 
    public class TreeNode { 
        int val = 0; 
        TreeNode left = null; 
        TreeNode right = null; 
     
        public TreeNode(int val) { 
            this.val = val; 
     
        } 
     
    } 
    */  
    public class Solution {  
        public boolean HasSubtree(TreeNode root1,TreeNode root2) {  
           boolean temp=false;     
           if(root1!=null && root2!=null){  
               if(root1.val==root2.val)                         //当遇到结点相等时,开始判断  
                  temp=doS(root1,root2);  
               if(!temp){                                      
                  temp=HasSubtree(root1.left,root2);            //结点不相等,再判断A树左节点  
               }  
               if(!temp){  
                  temp=HasSubtree(root1.right,root2);           //判断A树右节点  
               }  
           }  
          return temp;  
        }  
          
        public boolean doS(TreeNode root1,TreeNode root2)  
        {  
            if(root2==null)                                     //如果B树走完了,说明A树完全包含了B树  
                return true;    
            if(root1==null)                                     //如果A树走完了,B树未走完,说明A树不完全包含B树,记住和上面不能颠倒  
                return false;            
            if(root1.val!=root2.val)                            //判断结点是否相等,不相等返回false  
                return false;  
            return doS(root1.left,root2.left)&&doS(root1.right,root2.right);  //继续判断A树B树左节点,A树B树右节点  
        }  
     }  
    

    9.LeetCode110 Balanced Binary Tree(判断是不是平衡二叉树)

    Given a binary tree, determine if it is height-balanced.

    For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

    /** 
     * Definition for a binary tree node. 
     * public class TreeNode { 
     *     int val; 
     *     TreeNode left; 
     *     TreeNode right; 
     *     TreeNode(int x) { val = x; } 
     * } 
     */  
    class Solution {  
        boolean result=true;  
        public boolean isBalanced(TreeNode root) {  
            TestIsBalanced(root);  
            return result;  
        }  
        public int TestIsBalanced(TreeNode root){  
            if(root==null)  
                return 0;  
            int l=TestIsBalanced(root.left);  
            int r=TestIsBalanced(root.right);  
            if(Math.abs(l-r)>1)              //注意绝对值用法  
                 result=false;               //注意这里没有return  
            return 1+Math.max(l,r);  
            }  
    }  
    

    10.求二叉树的最大宽度

    public static int getMaxWidth(TreeNode root) {  
            if (root == null)  
                return 0;  
      
            Queue<TreeNode> queue = new ArrayDeque<TreeNode>();  
            int maxWitdth = 1; // 最大宽度  
            queue.add(root); // 入队  
      
            while (true) {  
                int len = queue.size(); // 当前层的节点个数  
                if (len == 0)  
                    break;  
                while (len > 0) {// 如果当前层,还有节点  
                    TreeNode t = queue.poll();  
                    len--;  
                    if (t.left != null)  
                        queue.add(t.left); // 下一层节点入队  
                    if (t.right != null)  
                        queue.add(t.right);// 下一层节点入队  
                }  
                maxWitdth = Math.max(maxWitdth, queue.size());  
            }  
            return maxWitdth;  
    }  
    

    可以举个栗子:

       1
      /  \
      2     3
     /  \  /  \
    4  5 6  7

    1 true len=1>0 1出 len=0 2,3入 1<2 maxWidth=2
    2 true len=2>0 2出 len=1 4,5入
    3 true len=1>0 3出 len=0 6,7入 2<4 maxWidth=4

    11.二叉树的前序遍历,中序遍历,后序遍历,层序遍历
    先分析下这四个:

    前序遍历:前序遍历的顺序为先到根节点,再到左节点,最后到右节点;
    5 2 1 4 3 6 8 7 9 11 10
    中序遍历:中序遍历就是先到左子树、再到根节点、最后到右子树;
    1 2 3 4 5 6 7 8 9 10 11
    后序遍历:对于后序遍历而言,其访问顺序是先访问左节点,再访问右节点,最后才访问根节点;
    1 3 4 2 7 10 11 9 8 6 5
    层序遍历:层序遍历就是按照二叉树的层次由上到下的进行遍历,每一层要求访问的顺序为从左到右;
    5 2 6 1 4 8 3 7 9 11 10
    ⑴前序遍历
    递归:

    /**
     * Definition of TreeNode:
     * public class TreeNode {
     *     public int val;
     *     public TreeNode left, right;
     *     public TreeNode(int val) {
     *         this.val = val;
     *         this.left = this.right = null;
     *     }
     * }
     */
    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Preorder in ArrayList which contains node values.
         */
    
    
        ArrayList<Integer> list = new ArrayList<Integer>();
        public ArrayList<Integer> preorderTraversal(TreeNode root) {
      
            if(root == null) return list;
            list.add(root.val);
            preorderTraversal(root.left);
            preorderTraversal(root.right);
            return list;
        }
    }
    

    非递归:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public List<Integer> preorderTraversal(TreeNode root) {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            List<Integer> traversal = new ArrayList<Integer>();
            if(root!=null){
                stack.push(root);
                while(!stack.isEmpty()){
                    TreeNode curr = stack.pop();
                    traversal.add(curr.val);
                    if(curr.right!=null){ stack.push(curr.right); }
                    if(curr.left!=null) { stack.push(curr.left);  }
                }
            }
            return traversal;
        }
    }
    

    ⑵中序遍历
    递归:

    /**
     * Definition of TreeNode:
     * public class TreeNode {
     *     public int val;
     *     public TreeNode left, right;
     *     public TreeNode(int val) {
     *         this.val = val;
     *         this.left = this.right = null;
     *     }
     * }
     */
    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Inorder in ArrayList which contains node values.
         */
        private ArrayList<Integer> List=new ArrayList<Integer>();
        public ArrayList<Integer> inorderTraversal(TreeNode root) {
            // write your code h
            if(root==null){return List;}
            inorderTraversal(root.left);
            List.add(root.val);
            inorderTraversal(root.right);
            return List;
        }
    }
    

    非递归:

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<Integer>();
    
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode cur = root;
    
        while(cur!=null || !stack.empty()){
            while(cur!=null){
                stack.add(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            list.add(cur.val);
            cur = cur.right;
        }
    
        return list;
    }
    

    ⑶后序遍历
    递归:

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Postorder in ArrayList which contains node values.
         */
        private ArrayList<Integer> List=new ArrayList<Integer>();
        public ArrayList<Integer> postorderTraversal(TreeNode root) {
            if(root==null){return List;}
            postorderTraversal(root.left);
            postorderTraversal(root.right);
            List.add(root.val);
            return List;
        }
    }
    

    非递归:

    class Solution {
        public List<Integer> postorderTraversal(TreeNode root) {
            LinkedList<Integer> ans = new LinkedList<Integer>();
            Stack<TreeNode> stack = new Stack<TreeNode>();
            if (root == null) return ans;
            stack.push(root);
            while (!stack.isEmpty()) {
            TreeNode cur = stack.pop();
            ans.addFirst(cur.val);
            if (cur.left != null) {
                stack.push(cur.left);
            }
            if (cur.right != null) {
                stack.push(cur.right);
            } 
        }
        return ans;
        }
    }
    

    ⑷层序遍历

       /** 
         *  
         * @param root 树根节点 
         * 层序遍历二叉树,用队列实现,先将根节点入队列,只要队列不为空,然后出队列,并访问,接着讲访问节点的左右子树依次入队列 
         */  
        public static void levelTravel(Node root){  
            if(root==null)return;  
            Queue<Node> q=new LinkedList<Node>();  
            q.add(root);  
            while(!q.isEmpty()){  
                Node temp =  q.poll();  
                System.out.println(temp.value);  
                if(temp.left!=null)q.add(temp.left);  
                if(temp.right!=null)q.add(temp.right);  
            }  
        }  
    

    12.二叉树的所有路径

    Given a binary tree, return all root-to-leaf paths.For example, given the following binary tree:

       1
      /  \
      2     3
       \
       5

    输出:
    ["1->2->5", "1->3"]

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public List<String> binaryTreePaths(TreeNode root) {
           List<String> test=new ArrayList<String>();   //数组是对象,引用传递
           if(root!=null) searchBT(root,"",test);
           return test;
        }
        public void searchBT(TreeNode root,String path,List<String> test)
        {
            if((root.left==null)&&(root.right==null)) test.add(path+root.val);//注意r:string+int就是string了 
            if(root.left!=null)  searchBT(root.left,path+root.val+"->",test);
            if(root.right!=null) searchBT(root.right,path+root.val+"->",test);    
        }
    }
    

    相关文章

      网友评论

          本文标题:LeetCode二叉树算法整理

          本文链接:https://www.haomeiwen.com/subject/fbnjzftx.html