【leetcode学习笔记】二叉树

本文深入探讨了二叉树的解题思路,包括树形动态规划方法,通过实例解释如何判断二叉搜索树和平衡二叉树。通过递归策略获取子树信息,结合节点值进行验证,有效解决这类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、二叉树

1.1 二叉树的基本结构

二叉树是由若干节点构成的结构,这些节点之间存在以下关系:

  • 存在一个根节点
  • 每个节点之多存在两个后继节点,分别称为左孩子和右孩子
  • 任何地方均不存在环

1.2 二叉树的解题套路

树形DP,是指如果一个问题可以通过向左右子树分别要信息,再经过简单的组合就可拿到时。可采用的套路。具体步骤为:

  • 思考如果想得到结果,我们需要想左右子树分别要什么信息?
  • 通过左右子树的这些信息,我们怎么组合出父节点的相应信息,从而继续让上方的父节点调用?

例:判断一个二叉树是否为二叉搜索树

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

二叉搜索树:任何一个节点的左子树中,只包含比他小的数;任何一个节点的右子树中,只包含比他大的数。

分析:

  • 确认一棵树是二叉搜索树,我们需要拿到以下信息:第一,左右子树是不是都是二叉搜索树,根节点的值是否大于左子树的最大值,是否小于右子树的最小值。--> 需要的信息为:是否是二叉搜索树、最大值、最小值
  • 如何根据左右子树的三个上述信息,得到整棵树的三个信息?

解答:

class ReturnData{
    public long maxValue;
    public long minValue;
    public boolean isBST;
}

class Solution {
    public boolean isValidBST(TreeNode root) {
        return isBST(root).isBST;
    }

    public ReturnData isBST(TreeNode root){
        if(root == null){
            ReturnData returnData = new ReturnData();
            returnData.minValue = Long.MAX_VALUE;
            returnData.maxValue = Long.MIN_VALUE;
            returnData.isBST = true;
            return returnData;
        }
        ReturnData leftData = isBST(root.left);
        ReturnData rightData = isBST(root.right);
        ReturnData returnData = new ReturnData();
        returnData.minValue = Math.min(Math.min(leftData.minValue, rightData.minValue), root.val);
        returnData.maxValue = Math.max(Math.max(leftData.maxValue, rightData.maxValue), root.val);
        returnData.isBST = (leftData.maxValue < root.val) && (rightData.minValue > root.val) && leftData.isBST && rightData.isBST;
        return returnData;
    }
}

例:判断一棵树是否是平衡二叉树

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

平衡二叉树:任何一个节点的左右子树深度差不超过1。

分析:所需信息为,是否为平衡二叉树,和深度。

解答:

class ReturnData{
    public int depth;
    public boolean isBST;
}

class Solution {
    public boolean isBalanced(TreeNode root) {
        return isBalancedTree(root).isBST;
    }

    public ReturnData isBalancedTree(TreeNode root){
        ReturnData returnData = new ReturnData();
        if(root == null){
            returnData.depth = 0;
            returnData.isBST = true;
        }else{
            ReturnData leftData = isBalancedTree(root.left);
            ReturnData rightData = isBalancedTree(root.right);

            returnData.depth = Math.max(leftData.depth, rightData.depth) + 1;
            returnData.isBST = leftData.isBST && rightData.isBST && Math.abs(leftData.depth - rightData.depth) <= 1;
        }
        return returnData;
    }
}

例:求两个节点的最低公共祖先

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

解答:

class ReturnData {
    public boolean containP;
    public boolean containQ;
    public TreeNode res;
}

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return getLCA(root, p, q).res;
    }

    public ReturnData getLCA(TreeNode root, TreeNode p, TreeNode q){
        ReturnData returnData = new ReturnData();
        if(root == null){
            returnData.containP = false;
            returnData.containQ = false;
            returnData.res = null;
        }
        else{
            ReturnData leftData = getLCA(root.left, p, q);
            ReturnData rightData = getLCA(root.right, p, q);
            if(leftData.res != null){
                return leftData;
            }
            if(rightData.res != null){
                return rightData;
            }
            returnData.containP = leftData.containP || rightData.containP || root == p;
            returnData.containQ = leftData.containQ || rightData.containQ || root == q;
            returnData.res = (returnData.containP && returnData.containQ) ? root : null;
        }
        return returnData;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值