二叉树的涉及的题

二叉树的定义

public static class TreeNode {
       int val;
       TreeNode left;
       TreeNode right;
       TreeNode(int x) { 
      	  val = x;
        }
   }

1.二叉树的最大深度

https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

    public int maxDepth(TreeNode root) {  
        if(root!=null){
             int left =  maxDepth(root.left);
             int right = maxDepth(root.right);
             return Math.max(left,right)+1;
        }else{
            return 0;      
        }
 }

2.二叉树的最小深度

https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/

 public static int minDepth(TreeNode root) {
       if(root == null) {
            return 0;
        }
        if ((root.left == null) && (root.right == null)) {
            return 1;
        }
        int minDepth = Integer.MAX_VALUE;
        if(root.left != null) {
            minDepth = Math.min(minDepth, minDepth(root.left));
        }
        
        if(root.right != null) {
            minDepth = Math.min(minDepth, minDepth(root.right));
        }
        
        return minDepth + 1;
    }
        }

3.求完全二叉树中节点的个数

https://leetcode-cn.com/problems/count-complete-tree-nodes/

  public int countNodes(TreeNode root) {
        if(root==null){
           return 0;
        }
         int left = countNodes(root.left);
         int right = countNodes(root.right);
         return left+right +1;
        
    }

4. 平衡二叉树

https://leetcode-cn.com/problems/balanced-binary-tree/

class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root == null)
            return true;
        if(Math.abs(getDepth(root.left)-getDepth(root.right))<=1){      
            return isBalanced(root.left) &&isBalanced(root.right);   
        }else{
            return false;
        }
    }
    //树的深度
    public int getDepth(TreeNode root){
        if(root == null)
            return 0;
        int left = getDepth(root.left);
        int right = getDepth(root.right);
        return Math.max(left,right)+1;
    }
}

5.二叉树的完全性检验

https://leetcode-cn.com/problems/check-completeness-of-a-binary-tree/

class Solution {
   public boolean isCompleteTree(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        //加入根节点
        queue.add(root);
        boolean hasNoChild = false;
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if (hasNoChild) {
     //上一层中左子树不为空,右子树为空,如果遍历到左子树,这时候左子树有孩子,则代表上一层不完全填满
                if(node.left!=null || node.right!=null){
                    return false;
                }
            } else {
                if (node.left != null && node.right != null) {  //左右子树不为空
                    queue.add(node.left);
                    queue.add(node.right);
                } else if (node.left != null && node.right == null) { //左子树不为空,右子树为空
                    queue.add(node.left);
                    hasNoChild = true;
                } else if (node.left == null && node.right != null) {//左子树为空,右子树不为空
                    return false;
                } else {  //左右子树都为空
                    hasNoChild = true;
                }
            }
        }
        return true;
    }
}

6.相同的树

https://leetcode-cn.com/problems/same-tree/

class Solution {
    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);
    }
}

7.对称二叉树

https://leetcode-cn.com/problems/symmetric-tree/

class Solution {
   public static boolean isSymmetric(TreeNode root) {
        if(root == null)
            return true;
        return Symmetric(root.left,root.right);
    }
    public static boolean Symmetric(TreeNode leftroot,TreeNode rightroot) {
        if(leftroot==null && rightroot==null)
            return true;
        if(leftroot==null || rightroot == null)
            return false;
        if(leftroot.val != rightroot.val)
            return false;
        return Symmetric(leftroot.left,rightroot.right) && Symmetric(leftroot.right,rightroot.left);
    }
}
class Solution {
   public static boolean isSymmetric(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        queue.add(root);
        while(!queue.isEmpty()){
            TreeNode node1 = queue.poll();
            TreeNode node2 = queue.poll();
           
            if(node1==null && node2==null)
                continue;
            if(node1==null || node2==null)
                return false;
             if(node1.val!=node2.val)
                return false;
            queue.add(node1.left);
            queue.add(node2.right);
            queue.add(node1.right);
            queue.add(node2.left);
        }
        return true;
    }
}

8.翻转二叉树

https://leetcode-cn.com/problems/invert-binary-tree/

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

9.二叉搜索树的最近公共祖先

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/

class Solution {
     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //都在右子树
        if(p.val >root.val && q.val >root.val){
            return lowestCommonAncestor(root.right,p,q);
        }else if(p.val<root.val && q.val <root.val){ //都在左子树
            return lowestCommonAncestor(root.left,p,q);
        }else{ //一个在左子树,一个在右子树
            return root;
        }
    }
}

10.二叉树的最近公共祖先

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

class Solution {
    TreeNode lowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q){
        if(root==null || root==p || root == q)
            return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        return left==null ? right : right == null?left:root;
    }
}

11.最深叶节点的最近公共祖先

https://leetcode-cn.com/problems/lowest-common-ancestor-of-deepest-leaves/

class Solution {
    public TreeNode lcaDeepestLeaves(TreeNode root) {
        if (root == null){
            return null;
        }
        //左子树的深度
        int left = depth(root.left);
        int right = depth(root.right);
        //如果左右子树深度相同,表示获取到了最深叶子节点的最近公共祖先
        if (left == right){
            return root;
        //如果左右子树不等高,高度小的那个子树节点的叶子节点的深度肯定不是最深的(因为比高度大的子树深度小)。
        //所以,最深叶子节点肯定在深度较大的子树当中,采用深度优先搜索,每次只要继续往深度更大的子树进行递归即可。
        }else if(left > right){
            return lcaDeepestLeaves(root.left);
        }else {
            return lcaDeepestLeaves(root.right);
        }
    }
	//求二叉树的深度
    private int depth(TreeNode root){
        if (root == null){
            return 0;
        }
        int left = depth(root.left);
        int right = depth(root.right);
        return 1 + Math.max(left,right);
    }
}

12.节点与其祖先中间的最大差值

https://leetcode-cn.com/problems/maximum-difference-between-node-and-ancestor/

class Solution {
  
    public static int maxAncestorDiff(TreeNode root) {
        if(root == null)
            return 0;
        return AncestorDiff(root,root.val,root.val);
       
    }
    // 每条从根节点到叶子节点的路径中的最大值和最小值,并求出差值更新全局变量
    //一口气遍历到叶子节点,遍历的时候动态保存当前路径的最大节点值和最小节点值
    //每当遍历一次叶子节点,将保存好的最大值与最小值之间的差与全局变量 maxvalue 比较,并且取较大值
    private static int AncestorDiff(TreeNode root, int max_value, int min_value) {
        if(root == null)
            return max_value-min_value;
        max_value = root.val > max_value ? root.val : max_value;
        min_value = root.val < min_value ? root.val : min_value;
        return Math.max(AncestorDiff(root.left,max_value,min_value),AncestorDiff(root.right,max_value,min_value));
    }

}

13.从前序与中序遍历序列构造二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0 || inorder.length == 0)
            return null;
         //前序的第一个数即为树的根结点
        TreeNode root = new TreeNode(preorder[0]);
        for(int i = 0;i<inorder.length;i++){
            //找到中序中的根节点
            if(preorder[0] == inorder[i]){
                //pre[1,i+1] 和in[0,i]构成左子树的遍历
                root.left = buildTree(Arrays.copyOfRange(preorder,1,i+1),Arrays.copyOfRange(inorder,0,i));
                //pre[i+1,len-1]和in[i+1,len-1]构成右子树的遍历
                root.right = buildTree(Arrays.copyOfRange(preorder,i+1,preorder.length),Arrays.copyOfRange(inorder,i+1,inorder.length));
                break;
            }
        }
        return root; 
    }
}

14.从中序与后序遍历序列构造二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

class Solution {
    public static TreeNode buildTree(int[] inorder, int[] postorder) {
            if(inorder.length == 0||postorder.length == 0)
                return null;
            //后序的最后一个为根结点
            TreeNode root = new TreeNode(postorder[postorder.length-1]);
            for(int i = 0;i<inorder.length;i++){
            //找到中序中的根节点位置
                if(inorder[i] == postorder[postorder.length-1]){
                  //in[0,i]和pos[0,i-1]构成左子树的遍历
                    root.left = buildTree(Arrays.copyOfRange(inorder,0,i),Arrays.copyOfRange(postorder,0,i));
                     //in[i+1,len-1]和pos[i,len-2]构成左子树的遍历
                    root.right = buildTree(Arrays.copyOfRange(inorder,i+1,inorder.length),Arrays.copyOfRange(postorder,i,postorder.length-1));
                    break;
                }
            }
            return root;
        }
}

15.把二叉树转换成累加树

https://leetcode-cn.com/problems/convert-bst-to-greater-tree/

//中序遍历结果为从小到大,要变成累加树,则中序遍历反过来相加变成节点值即可。
class Solution {
    int num = 0;
    public TreeNode convertBST(TreeNode root) {
        if(root!=null){
           //遍历右子树
           convertBST(root.right);
           //改变值,依次累加即可
           root.val = root.val+num;
           //存储上一层的值
           num = root.val;
           //遍历左子树
           convertBST(root.left);
       }
        return root;
    }
}

16.不同的二叉搜索树

https://leetcode-cn.com/problems/unique-binary-search-trees/

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
动态规划

  • 初始化
    假设n个节点存在二叉搜索树的个数是dp(n),令f(i) 为以i为根的二叉搜索树的个数,则有
               dp(n) = f(1) + f(2) + f(3) +... + f(n)
    当i为根节点时,其左子树的个数为(i - 1),右子树的个数为(n-i),则
               f(i) = dp(i-1) *dp(n-i)
    结合两个式子可以得到卡特兰数:
               dp(n) = dp(0) *dp(n-1) +dp(1) *dp(n-2) +... +dp(n-1)*dp(0)
                    = dp(n-1) * C(2n,n)
                    = dp(n-1) * (4*n-2)/(n-1)
class Solution {
  public static int numTrees(int n) {
        //n个节点存在二叉树的个数
        long []dp = new long[n+1];
        //以i为根节点的二叉树个数
        dp[0] = 1; //以0为根节点的二叉树的个数,即为空树
        dp[1] = 1; //以1为根节点的二叉树的个数,即root.val = 1的树
        for(int i = 1;i<=n;i++){
            dp[i] = dp[i-1]*(4*i-2)/(i+1);
        }
        return (int) dp[n];
    }
}

17.不同的二叉搜索树 II

https://leetcode-cn.com/problems/unique-binary-search-trees-ii/

class Solution {
    public List<TreeNode> generateTrees(int n) {
        if(n<=0)    
            return new ArrayList<TreeNode>();
        return generate(1,n);
    }
    public List<TreeNode> generate(int start,int end){
        List<TreeNode> res=new ArrayList<>();
        if(start>end){
            res.add(null);
            return res;
        }
        for(int i=start;i<=end;i++){
            // 递归遍历左子树
            List<TreeNode> leftTrees=generate(start,i-1);
            // 递归遍历右子树
            List<TreeNode> rightTrees=generate(i+1,end);
            //先序遍历存入以i为根节点的二叉搜索树
            for(TreeNode left:leftTrees){
                for(TreeNode right:rightTrees){
                    TreeNode root=new TreeNode(i);
                    root.left=left;
                    root.right=right;
                    res.add(root);
                }
            }
        }
        return res;
    }
}

18.在二叉树中增加一行

https://leetcode-cn.com/problems/add-one-row-to-tree/

class Solution {
      public static TreeNode addOneRow(TreeNode root, int v, int d) {
           TreeNode node = new TreeNode(v);
           //如果 d 的值为 1,深度 d - 1 不存在,则创建一个新的根节点 v,原先的整棵树将作为 v 的左子树。
            if(d == 1){
                node.left = root;
                return node;
            }
            if(d == 0){
                node.right = root;
                return node;
            }
            if(root != null && d>1){
                root.left = addOneRow(root.left ,v, d > 2 ? d - 1 : 1);
                root.right = addOneRow(root.right,v, d > 2 ? d - 1 : 0);
            }
            return root;
      }
}

19.验证一棵树是不是二叉搜索树

https://leetcode-cn.com/problems/validate-binary-search-tree/

//根据二叉搜索树的中序遍历为从小到大的思路写的
//修改一下二叉搜索树的非递归写法
class Solution {
    public boolean isValidBST(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        //这里不能写成 Double.MIN_VALUE,调试时边界值有点变态啊
        double inorder = - Double.MAX_VALUE;
        while(!stack.isEmpty() || root != null){
            while (root!=null){
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            if(root.val <= inorder){
                return false;
            }
            inorder = root.val;
            root = root.right;
        }
        return true;
    }
}
class Solution {
     TreeNode pre = null;
    public boolean isValidBST(TreeNode root) {
      if (root == null) {
            return true;
        }
        if (!isValidBST(root.left)) {
            return false;
        }
        if (pre != null && pre.val >= root.val) {
            return false;
        }
        pre = root;
        return isValidBST(root.right);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值