JAVA入门算法题(十一)

版权声明:很高兴认识你,我叫邵龙飞 原创文章,转载请注明 https://blog.csdn.net/qq_37482202/article/details/88925403

一、倒置层序遍历

题目:

/**
 * 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
 * <p>
 * 例如:
 * 给定二叉树 [3,9,20,null,null,15,7],
 *      3
 *    / \
 *   9  20
 * /  \
 * 15  7
 * 返回其自底向上的层次遍历为:
 * [
 * [15,7],
 * [9,20],
 * [3]
 * ]
 */

 树的层序遍历有两种,一种用队列实现,一种用递归实现。

队列:使用while循环,只要队列不为空就循环。不断的取节点,按照左右节点顺序放入队列

递归:先递归算出树的高度,使用for循环,传入层次,递归找到该层

队列的时间复杂度比较低,但占用空间大,递归的时间复杂度高很多,但是占用空间小

这道题与层序遍历的区别就是倒置,可以使用list.add(0,item)来实现,或者栈

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

public List<List<Integer>> method1(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result;
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while (!q.isEmpty()) {
            int size = q.size();
            List<Integer> tmp = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode node = q.poll();
                tmp.add(node.val);
                if (node.left != null) q.offer(node.left);
                if (node.right != null) q.offer(node.right);
            }
            result.add(0, tmp);
        }
        return result;
    }

二、树的最小深度

题目:

/**
 * 给定一个二叉树,找出其最小深度。
 * 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
 * 说明: 叶子节点是指没有子节点的节点。
 * 示例:
 * 给定二叉树 [3,9,20,null,null,15,7],
 *     3
 *    / \
 *   9  20
 *     /  \
 *    15   7
 * 返回它的最小深度  2.
 */

 如果你会求树的最大深度,那么这道题就是它的翻版

直接使用递归,哪边深度小算哪边的

树的节点

    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
    public static int method1(TreeNode root) {
        if (root==null){
            return 0;
        }
        if (root.left==null){
            return method1(root.right)+1;
        }
        if (root.right==null){
            return method1(root.left)+1;
        }
        int left=method1(root.left)+1;
        int right=method1(root.right)+1;
        return left>right?right:left;
    }

优化一下代码

    public static int method2(TreeNode root){
        if(root==null)  return 0;
        int l =method2(root.left);
        int r =method2(root.right);
        if(l==0 ||r==0)
            return l+r+1;//在左子树和右子树中仅有一个存在的情况下,返回存在的值(即其中一颗树的minDepth为0)
        return Math.min(l,r)+1;//在左子树和右子树都存在的情况下返回两者最小值
    }

三、指定的路径和

题目:

/**
 * 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
 * 说明: 叶子节点是指没有子节点的节点。
 * 示例:
 * 给定如下二叉树,以及目标和 sum = 22,
 *          5
 *        / \
 *      4   8
 *     /   / \
 *   11  13  4
 *  /  \      \
 * 7    2      1
 * 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
 *
 */

树的结构

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

其实这就是一道树的遍历问题,可以使用前序遍历,中序遍历,后序遍历都可以,递归减去当前节点值,如果正好减到零且该节点是叶子节点,那么就返回true。不同路径返回值使用或逻辑运算符,只要找到一条即可

这里只演示一种前序遍历

    public boolean method1(TreeNode root, int sum) {
        if (root==null){
            return false;
        }
        int value=sum-root.val;
        if (value==0&&root.left==null&&root.right==null){
            return true;
        }
        return method1(root.left,value)||method1(root.right,value);
    }

四、高度平衡的二叉树

题目:

/**
 * 给定一个二叉树,判断它是否是高度平衡的二叉树。
 * 本题中,一棵高度平衡二叉树定义为:
 * 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
 * 示例 1:
 * 给定二叉树 [3,9,20,null,null,15,7]
 *         3
 *       / \
 *      9   20
 *   /  \
 * 15   7
 * 返回 true 。
 * 示例 2:
 * 给定二叉树 [1,2,2,3,3,null,null,4,4]
 *          1
 *        / \
 *      2   2
 *    / \
 *  3   3
 * / \
 * 4  4
 * 返回 false 。
 */

树的结构

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

第一种思路:遍历每一层,只要左右子树高度相差大于1就返回false,缺点就是递归套递归,时间复杂度高

    public static boolean method1(TreeNode root) {
        if (root==null)return true;
        int cha=Math.abs(getDepth(root.left)-getDepth(root.right));
        System.out.println(cha);
        if (cha>1){
            return false;
        }else {
            return method1(root.left)&&method1(root.right);
        }
    }

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

改进思路:倒序遍历整棵树,减少了递归,复杂度降低很多

    public static boolean method2(TreeNode root){
        return heightOf(root) != null;
    }

    private static Integer heightOf(TreeNode node) {
        if (node == null) return 0;
        Integer left = heightOf(node.left);
        Integer right = heightOf(node.right);
        return left == null || right == null || Math.abs(left - right) > 1 ? null : 1 + Math.max(left, right);
    }

猜你喜欢

转载自blog.csdn.net/qq_37482202/article/details/88925403
今日推荐