子树判断(更新版本)

一、问题描述:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)。

优化之前的解题思路:1)如果当前结点相同,则通过compare函数进行对比子树是否一样;

                                   2)compare函数通过遍历对两个树进行相似判断。

之前的博客:子树判断。但是存在一个问题:时间复杂度过高。根据评论建议,优化如下

                                   1)因为先序+中序遍历可以唯一确定一颗二叉树(后续+中序也可以,但是先序+后续不可以,先序+后续无法确定左右子树的关系)。

                                   2)序列化后,使用字符串匹配算法(KMP)。

二、代码实现:见我的github:TreeJudgeOps

三、解题思路:

3.1)子树序列化

        子树序列化(先序)

        子树序列化(中序)

3.2)字符串匹配(匹配过程详见:KMP算法的Java实现

四、注意事项:

1、TreeJudgeOps由于序列化的模式限制,仅仅可以用于全子串匹配,即子串的叶子结点等于源串的叶子结点,这种模式。

2、TreeJudge可以用作部分子串匹配,相似即匹配。

### 判断二叉树是否为二叉排序树的方法 要判断一个树结构是否为二叉排序树(Binary Search Tree, BST),可以通过以下方法实现: #### 方法一:基于中序遍历的特性 二叉排序树的一个重要性质是,对其进行中序遍历时得到的结果序列应严格递增。因此,可以在中序遍历的过程中维护一个全局变量 `pre` 来存储前驱节点的值,并将其与当前节点的值进行比较。 以下是具体实现代码: ```c++ #include <iostream> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; bool isBSTUtil(TreeNode* root, long& prev) { if (root == nullptr) return true; // 如果为空,则认为该部分满足条件 // 验证左子树 if (!isBSTUtil(root->left, prev)) return false; // 当前节点应该大于之前的节点 if (root->val <= prev) return false; prev = root->val; // 更新前驱节点的值 // 验证右子树 return isBSTUtil(root->right, prev); } bool isValidBST(TreeNode* root) { long prev = LONG_MIN; // 初始化前驱节点为最小可能值 return isBSTUtil(root, prev); } ``` 这种方法的时间复杂度为 \(O(n)\),空间复杂度取决于递归栈深度,通常为 \(O(h)\),其中 \(h\) 是树的高度[^1]。 --- #### 方法二:范围约束法 另一种常见的方法是对每个节点施加一定的取值范围限制。对于任意节点 \(N\) 而言,其左子树中的所有节点都必须小于 \(N\) 的值,而右子树中的所有节点都必须大于 \(N\) 的值。通过递归传递允许的最大值和最小值来验证这一属性。 下面是具体的实现代码: ```cpp bool validateBSTHelper(TreeNode* node, long minVal, long maxVal) { if (node == nullptr) return true; // 空节点总是合法的 // 检查当前节点是否超出指定范围 if (node->val <= minVal || node->val >= maxVal) return false; // 对左右子树分别递归检查 return validateBSTHelper(node->left, minVal, node->val) && validateBSTHelper(node->right, node->val, maxVal); } bool isValidBST(TreeNode* root) { return validateBSTHelper(root, LONG_MIN, LONG_MAX); } ``` 此方法同样具有时间复杂度 \(O(n)\) 和空间复杂度 \(O(h)\)[^4]。 --- #### Java 实现版本 如果是使用 Java 编程语言,也可以采用类似的逻辑。下面提供了一个基于范围约束法的 Java 版本实现: ```java public class Solution { public boolean isValidBST(TreeNode root) { return helper(root, Long.MIN_VALUE, Long.MAX_VALUE); } private boolean helper(TreeNode node, long lowerBound, long upperBound) { if (node == null) return true; if (node.val <= lowerBound || node.val >= upperBound) return false; return helper(node.left, lowerBound, node.val) && helper(node.right, node.val, upperBound); } } ``` 这段代码利用了辅助函数 `helper` 并传入上下界参数以完成验证过程[^5]。 --- ### 注意事项 - **重复值处理**:某些定义下不允许二叉排序树中有相同键值的情况存在;此时需特别注意调整比较操作符。 - **边界情况测试**:务必考虑极端情形如单节点树或者完全倾斜链表形式的输入数据集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值