【数据结构】二叉树

1 相同的树

在这里插入图片描述

public class Code02_SameTree {

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

    public static boolean isSameTree(TreeNode p, TreeNode q) {
        // 一个为空 一个不为空
        if (p == null ^ q == null) {
            return false;
        }
        
        // 都为空
        if (p == null) {
            return true;
        }

        // 值相同且左右子树都相同
        return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

2 对称二叉树

在这里插入图片描述

public class Code03_SymmetricTree {
    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;
        }
    }

    public static boolean isSymmetric(TreeNode root) {
        return isMirror(root, root);
    }

    private static boolean isMirror(TreeNode p, TreeNode q) {
        if (p == null ^ q == null) {
            return false;
        }

        if (p == null) {
            return true;
        }

        return p.val == q.val && isMirror(p.left, q.right) && isMirror(p.right, q.left);
    }
}

3 二叉树的最大深度

在这里插入图片描述

public class Code04_MaximumDepthOfBinaryTree {
    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;
        }
    }

    public static int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }

        return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
    }
}

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

在这里插入图片描述

public class Code05_ConstructBinaryTreeFromPreorderAndInorderTraversal {

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

        TreeNode(int val) {
            this.val = val;
        }
    }

    public static TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder == null || inorder == null || preorder.length != inorder.length) {
            return null;
        }

        Map<Integer, Integer> inMap = new HashMap<>(inorder.length);
        for (int i = 0; i < inorder.length; i++) {
            inMap.put(inorder[i], i);
        }

        return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, inMap);
    }

    public static TreeNode buildTree(int[] preorder, int pL, int pR,
                                     int[] inorder, int iL, int iR, Map<Integer, Integer> inMap) {
        if (pL > pR) {
            return null;
        }

        // 只有一个值
        TreeNode head = new TreeNode(preorder[pL]);
        if (pL == pR) {
            return head;
        }

        // 中序遍历的根节点索引
        Integer iRoot = inMap.get(preorder[pL]);
        head.left = buildTree(preorder, pL + 1, pL + iRoot - iL, inorder, iL, iRoot - 1, inMap);
        head.right = buildTree(preorder, pL + iRoot - iL + 1, pR, inorder, iRoot + 1, iR, inMap);

        return head;
    }
}

5 二叉树的层序遍历

在这里插入图片描述

public class Code02_BalancedBinaryTree {
    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;
        }
    }

    public static class Info {
        /**
         * 高度.
         */
        private int height;

        /**
         * 是否平衡.
         */
        private boolean isBalanced;

        public Info(int height, boolean isBalanced) {
            this.height = height;
            this.isBalanced = isBalanced;
        }
    }

    public static boolean isBalanced(TreeNode root) {
        return process(root).isBalanced;
    }

    /**
     * 返回 node 节点的平衡信息和高度信息.
     */
    public static Info process(TreeNode node) {
        if (node == null) {
            return new Info(0, true);
        }

        // 左右子树的平衡信息
        Info lInfo = process(node.left);
        Info rInfo = process(node.right);

        // 当前节点高度信息
        int height = Math.max(lInfo.height, rInfo.height) + 1;
        // 当前节点平衡信息
        boolean isBalanced = lInfo.isBalanced && rInfo.isBalanced && Math.abs(lInfo.height - rInfo.height) < 2;

        return new Info(height, isBalanced);
    }
}

6 是否是平衡二叉树

在这里插入图片描述

public class Code02_BalancedBinaryTree {
    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;
        }
    }

    public static class Info {
        /**
         * 高度.
         */
        private int height;

        /**
         * 是否平衡.
         */
        private boolean isBalanced;

        public Info(int height, boolean isBalanced) {
            this.height = height;
            this.isBalanced = isBalanced;
        }
    }

    public static boolean isBalanced(TreeNode root) {
        return process(root).isBalanced;
    }

    /**
     * 返回 node 节点的平衡信息和高度信息.
     */
    public static Info process(TreeNode node) {
        if (node == null) {
            return new Info(0, true);
        }

        // 左右子树的平衡信息
        Info lInfo = process(node.left);
        Info rInfo = process(node.right);

        // 当前节点高度信息
        int height = Math.max(lInfo.height, rInfo.height) + 1;
        // 当前节点平衡信息
        boolean isBalanced = lInfo.isBalanced && rInfo.isBalanced && Math.abs(lInfo.height - rInfo.height) < 2;

        return new Info(height, isBalanced);
    }
}

7 路径总和

在这里插入图片描述

public class Code03_PathSum {

    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;
        }
    }

    public static boolean isSum;

    public static boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return false;
        }

        isSum = false;
        process(root, 0, targetSum);
        return isSum;
    }

    /**
     * 方法1 
     */
    public static void process(TreeNode node, int preSum, int targetSum) {
        // 叶子节点
        if (node.left == null && node.right == null) {
            if (preSum + node.val == targetSum) {
                isSum = true;
            }
            // 叶子返回
            return;
        }

        // 路径和
        preSum += node.val;
        if (node.left != null) {
            process(node.left, preSum, targetSum);
        }
        if (node.right != null) {
            process(node.right, preSum, targetSum);
        }
    }

    /**
     * 方法2 
     */
    public static boolean process(TreeNode node, int sum) {
        // 叶子节点
        if (node.left == null && node.right == null) {
            return node.val == sum;
        }

        // 非叶子节点
        boolean ans = node.left != null && process(node.left, sum - node.val);
        ans |= (node.right != null && process(node.right, sum - node.val));
        return ans;
    }
}

8 路径总和 II

在这里插入图片描述

public class Code04_PathSumII {

    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;
        }
    }

    public static List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> ans = new ArrayList<>();
        if (root == null) {
            return ans;
        }

        process(root, new ArrayList<>(), 0, targetSum, ans);
        return ans;
    }

    public static void process(TreeNode node, List<Integer> path,
                               int preSum, int targetSum, List<List<Integer>> ans) {
        // 叶子节点
        if (node.left == null && node.right == null) {
            if (node.val + preSum == targetSum) {
                path.add(node.val);
                ans.add(new ArrayList<>(path));
                // 恢复路径
                path.remove(path.size() - 1);
            }
            return;
        }

        // 非叶子节点
        path.add(node.val);
        preSum += node.val;
        if (node.left != null) {
            process(node.left, path, preSum, targetSum, ans);
        }
        if (node.right != null) {
            process(node.right, path, preSum, targetSum, ans);
        }
        // 恢复路径
        path.remove(path.size() - 1);
    }
}

9 是否是二叉搜索树

在这里插入图片描述

public class Code05_IsBinarySearchTree {

    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;
        }
    }

    public static class Info {
        private boolean isBST;
        private int max;
        private int min;

        public Info(boolean isBST, int max, int min) {
            this.isBST = isBST;
            this.max = max;
            this.min = min;
        }
    }

    public static boolean isValidBST(TreeNode node) {
        if (node == null) {
            return true;
        }

        return process(node).isBST;
    }

    public static Info process(TreeNode node) {
        if (node == null) {
            return null;
        }

        Info lInfo = process(node.left);
        Info rInfo = process(node.right);

        // 当前节点的最大最小值
        int max = node.val;
        int min = node.val;
        if (lInfo != null) {
            max = Math.max(lInfo.max, max);
            min = Math.min(lInfo.min, min);
        }
        if (rInfo != null) {
            max = Math.max(rInfo.max, max);
            min = Math.min(rInfo.min, min);
        }


        boolean isLeftBST = lInfo == null || lInfo.isBST;
        boolean isRightBSt = rInfo == null || rInfo.isBST;
        boolean isLeftMaxLess = lInfo == null || lInfo.max < node.val;
        boolean isRightMinMore = rInfo == null || rInfo.min > node.val;

        boolean isBST = isLeftBST && isRightBSt && isLeftMaxLess && isRightMinMore;

        return new Info(isBST, max, min);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值