另一个树的子树

https://leetcode-cn.com/problems/subtree-of-another-tree/description/

给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

示例 1:
给定的树 s:

     3
    / \
   4   5
  / \
 1   2

给定的树 t:

   4 
  / \
 1   2

返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。

示例 2:
给定的树 s:

     3
    / \
   4   5
  / \
 1   2
    /
   0

给定的树 t:

   4
  / \
 1   2

返回 false。
思路;

首先比较s树和t树的根节点是否相等,调用isSameTree()判断它们是否是相等的树
然后递归判断左子树的根节点去比较,以此类推
在这里插入图片描述

实现

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

//判断两个树是否相等
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if(p == NULL && q == NULL)
        return true;
    if(p == NULL || q == NULL)
        return  false;
    return p->val == q->val
        && isSameTree(p->left, q->left)
        && isSameTree(p->right, q->right);
}

bool isSubtree(struct TreeNode* s, struct TreeNode* t) {
    //t == NULL 是所有树的子树
    if(t == NULL)
        return true;
    //s == NULL 母树为空,子树一定为空,走第一个if条件
    if(s == NULL)
        return false;  
    //判断节点相等,并且是、相等的树
    if(s->val == t->val && isSameTree(s, t))
            return true;
    //递归判断下一个结点是不是t的母树
    return isSubtree(s->left, t)
        || isSubtree(s->right, t);  
}
<think> 首先,用户的问题是:“我想了解在平衡中比较左右子树深度的方法”。用户提到了平衡,并询问如何比较左右子树的深度。从系统指令中,我需要使用中文回答,结构化清晰,并遵循LaTeX格式。 回顾引用:[^1] 展示了一个C语言的函数,用于计算的最大深度,并用于判断平衡。它递归地计算左右子树的深度,然后比较它们。[^2] 是Python代码,类似地计算深度,并在IsBalanced函数中比较。[^3] 是Java代码,同样方法。 用户的核心是“比较左右子树深度的方法”,这在引用中已经涉及。我需要解释这个方法,而不是直接复制代码。 关键点: - 平衡定义:对于每个节点,左右子树的高度差不超过1(通常定义为|height(left) - height(right)| <= 1)。 - 比较深度的方法:递归地计算每个节点的左右子树的高度(深度),然后检查差异。 步骤: 1. **计算深度**:定义一个函数(如maxDepth或depth),递归地计算的高度。 - 如果节点为空,深度为0。 - 否则,深度 = max(左子树深度, 右子树深度) + 1。 2. **判断平衡**:定义一个函数(如isBalance),递归地检查每个节点。 - 如果节点为空,是平衡的(返回true)。 - 计算左子树深度和右子树深度。 - 如果 |深度差| > 1,返回false。 - 否则,递归地检查左子树和右子树是否平衡。 在回答中,我应该用中文解释这个过程,包括公式和伪代码。 系统指令要求: - 行内数学表达式用$...$,例如深度计算:$\text{深度} = \max(\text{左子树深度}, \text{右子树深度}) + 1$。 - 独立公式用$$...$$,如果需要单独公式。 - 生成相关问题:在回答结束时添加相关问题。 - 引用的段落末尾添加引用标识,如[^1]。用户提供了引用,但我需要基于内容引用,而不是直接复制。 我的回答结构: - **引言**:解释平衡的概念和比较深度的重要性。 - **方法描述**: - 步骤1:计算深度的方法。 - 步骤2:比较深度并判断平衡。 - **示例**:用伪代码或简化代码说明。 - **注意事项**:提及时间复杂度或优化方法。 - **相关问题**:生成2-3个相关问题。 用LaTeX: - 深度计算:$ \text{depth}(node) = \begin{cases} 0 & \text{if } node = \text{null} \\ \max(\text{depth}(node.left), \text{depth}(node.right)) + 1 & \text{otherwise} \end{cases} $ - 平衡判断:$ |\text{depth}(left) - \text{depth}(right)| \leq 1 $ 确保回答真实可靠:基于标准算法知识,如AVL或一般平衡判断。 最终输出: - 回答用中文。 - 清晰结构。 - 结束时生成相关问题。 </think>### 平衡中比较左右子树深度的方法 在计算机科学中,平衡(如AVL)要求每个节点的左右子树高度差不超过1(即 $|\text{左子树深度} - \text{右子树深度}| \leq 1$)。比较左右子树深度是判断是否平衡的核心步骤,它通过递归计算高度并检查差异来实现。下面我将逐步解释这个方法,包括基本思路、算法步骤和注意事项。 #### 1. **基本思路** - **深度(高度)定义**:的深度指从根节点到最远叶子节点的最长路径长度(节点数)。例如,空的深度为0。 - **比较方法**: - 对于每个节点,递归计算其左子树和右子树的深度。 - 比较两个深度值:如果差异大于1,则该节点不平衡;否则,递归检查其左右子树。 - 整个平衡的条件是所有节点都满足 $|\text{depth}(left) - \text{depth}(right)| \leq 1$。 - 数学上表示: - 深度计算函数: $$ \text{depth}(node) = \begin{cases} 0 & \text{if } node = \text{null} \\ \max(\text{depth}(node.left), \text{depth}(node.right)) + 1 & \text{otherwise} \end{cases} $$ - 平衡判断:对于每个节点,需满足 $|\text{depth}(node.left) - \text{depth}(node.right)| \leq 1$。 #### 2. **算法步骤** 判断平衡的方法通常分为两个递归函数:一个用于计算深度,一个用于比较深度和递归检查子树平衡性。以下是伪代码描述(基于常见实现[^1][^2][^3]): - **步骤1:计算节点深度** - 如果节点为空,深度为0。 - 否则,递归计算左子树深度和右子树深度,取较大值加1。 - 伪代码: ```python def depth(node): if node is None: # 节点为空 return 0 left_depth = depth(node.left) # 递归计算左子树深度 right_depth = depth(node.right) # 递归计算右子树深度 return max(left_depth, right_depth) + 1 # 返回当前节点深度 ``` - 时间复杂度:$O(n)$,其中 $n$ 是节点数,因为每个节点只访问一次。 - **步骤2:比较深度并判断平衡** - 如果节点为空,直接视为平衡(返回true)。 - 计算左子树深度和右子树深度。 - 如果 $|\text{left_depth} - \text{right_depth}| > 1$,则不平衡(返回false)。 - 否则,递归检查左子树和右子树是否都平衡。 - 伪代码: ```python def is_balanced(node): if node is None: # 空是平衡的 return True left_depth = depth(node.left) # 调用深度函数 right_depth = depth(node.right) if abs(left_depth - right_depth) > 1: # 比较深度差异 return False return is_balanced(node.left) and is_balanced(node.right) # 递归检查子树 ``` - 时间复杂度:最坏情况下 $O(n^2)$,因为每个节点可能多次调用 `depth` 函数(针对优化见注意事项)。 #### 3. **注意事项** - **优化方法**:上述基础方法效率较低,因为重复计算深度。优化版可以在一个递归函数中同时返回深度和平衡状态,将时间复杂度降为 $O(n)$[^1][^3]。例如: - 定义辅助函数返回(深度, 是否平衡)。 - **常见错误**: - 只比较根节点的深度差,而不检查所有子树(必须递归到每个节点)。 - 忽略空或单节点的边界情况(深度为0或1)。 - 应用场景:平衡用于数据库索引、高效搜索(如AVL或红黑),确保操作时间复杂度为 $O(\log n)$。 这个方法直接来自平衡判断的标准算法,确保在插入或删除后保持高效性能[^1][^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值