首页 > 其他 > 详细

[leetcode刷题]—— 树(递归)

时间:2021-01-14 15:09:23      阅读:26      评论:0      收藏:0      [点我收藏+]

此篇博客主要记录使用递归求解的树相关的算法题。

 

一、二叉树的最大深度

104. 给定一个二叉树,找出其最大深度。 (easy) 2021-01-13

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7],

         3
       / \
    9  20
   /      \
15      7
返回它的最大深度 3 。

  常规递归题目。

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int leftDepth = maxDepth(root.left);
        int rightDepth = maxDepth(root.right);
        if(leftDepth > rightDepth){
            return leftDepth + 1;
        }else{
            return rightDepth + 1;
        }
    }
}

 

 二、平衡树

110.平衡二叉树   (easy) 2021-01-14

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

   题解:这道easy题目难度大于很多medium。最大的难点在于返回值的选择。使用递归时,如果返回左右子树是否为平衡二叉树,但是左右都是平衡二叉树不能说明就是平衡二叉树,还要左右子树的高度差小于1。如果递归返回高度信息也不合适,左右子树的高度差小于也证明不了平衡二叉树。

  照着这个思路,可以编写一个返回结点的类,包含此结点的高度信息和是否平衡信息,递归函数返回此结点。

  分析到这儿,就能想出更简便的方法了。设置一个全局变量,布尔型。递归函数的返回值使用树的高度,只要左右子树的高度信息相差大于1,则变量成true。

     

class Solution {
    boolean flag = true;
    public boolean isBalanced(TreeNode root) {
        depth(root);
        return flag;
    }
    public int depth(TreeNode root){
        if(root == null){
            return 0;
        }
        int l = depth(root.left);
        int r = depth(root.right);
        if(Math.abs(l - r) > 1){   //多一个判断标志
            flag = false;
        }
        return Math.max(l , r) + 1;
    }
}

 

三、二叉树的直径

543.二叉树的直径   (easy)  2021-01-14

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

示例 :
给定二叉树

         1
        / \
      2    3
    /        \
  4          5
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。

   题解:这一题与上一题及其相似。使用递归返回树的高度信息,定义一个全局变量记录当前结点的直径。每个结点的直径就是左子树长度加右子树长度,当然直径一直取较大值。

  

class Solution {
    int diameter;
    public int diameterOfBinaryTree(TreeNode root) {
        depth(root);
        return diameter;
    }
    public int depth(TreeNode root){
        if(root == null){
            return 0;
        }
        int l = depth(root.left);
        int r = depth(root.right);
        int nowDiameter = l + r;
        diameter = (diameter > nowDiameter) ? diameter : nowDiameter;
        return Math.max(l, r) + 1;

    }
}

 

 

四、翻转树

226.翻转二叉树  (easy)2021-01-14

翻转一棵二叉树。

示例:

输入:

             4
            / \
        2     7
       / \    / \
     1 3    6 9
输出:

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

  常规递归求解的题目。

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

 

五、合并二叉树

617.合并二叉树   (easy) 2021-01-14

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

输入:
Tree 1 Tree 2
       1                                 2
      / \                               / \
    3  2                           1    3
   / \                                       \
 5  4                                       7
输出:
合并后的树:
         3
        / \
    4       5
  /   \        \
5    4       7
注意: 合并必须从两个树的根节点开始

  常规递归的思路,就是内存占用较大,击败6%,诶。

  

class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        if(t1 == null) return t2;
        if(t2 == null) return t1;
     
        t1.left = mergeTrees(t1.left, t2.left);
        t1.right = mergeTrees(t1.right, t2.right);

        t1.val = t1.val + t2.val;   //以t1为主
        return t1;
    }
}

 

六、判断路径和是否等于一个数

112.路径总和   (easy)  2021-01-14

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 
给定如下二叉树,以及目标和 sum = 22,

              5
            /   \
         4      8
      /          / \
   11       13   4
   / \                \
7   2               1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

  这个测试用例绝了。

  技术分享图片

 

 

   

class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if(root == null)  return false;
        if(root.left == null && root.right == null && root.val == sum){
            return true; 
        }
        boolean l = hasPathSum(root.left, sum - root.val);
        boolean r = hasPathSum(root.right, sum - root.val);
        return l || r ;
    }
}

 

七、统计路径和等于一个数的路径数量

437.路径总和   (medium) 2021-01-14

给定一个二叉树,它的每个结点都存放着一个整数值。

找出路径和等于给定数值的路径总数。

路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

示例:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

                 10
              /         \
             5         -3
           /  \           \
        3     2        11
       /  \      \
     3   -2   1

返回 3。和等于 8 的路径有:

1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11

  题解:如果不是刚刚做了上面那个路径总和的题,这个题恐怕连思路都没。

    花了一个小时,结果时间击败10%, 空间击败12%,纪念一下,哈哈。

  

class Solution {
    int count = 0;
    public int pathSum(TreeNode root, int sum) {
        if(root == null) return 0;
        preOrder(root, sum);
        return count;
    }
    //前序遍历
    public void preOrder(TreeNode root, int sum){
        subtatal(root, sum);
        if(root.left != null){
            preOrder(root.left, sum);
        }
        if(root.right != null){
            preOrder(root.right, sum);
        }
    }
    //写一个函数判断以此结点为根结点时,是否有数值和满足的情况
    public int subtatal(TreeNode root, int sum){
        if(root == null){
            return count;
        }
        if(root != null && root.val == sum){
            count ++;
            //如果返回则忽略了后面正负数和为0的情况。
            //但是没有返回值,这个递归函数一直是false,虽然不需要用它的返回值
            //return true;                    
        }
        int l = subtatal(root.left, sum - root.val);
        int r = subtatal(root.right, sum - root.val);
        return count;
    }
}

 

[leetcode刷题]—— 树(递归)

原文:https://www.cnblogs.com/nobita/p/14276387.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!