剑指Offer26.树的子结构

  • 剑指Offer26.树的子结构

  • 题目:
    给定两棵二叉树A和B,判断B是不是A的子结构;
    空树不是任何树的子结构;

  • 思路:
    1.递归:O(mn):m是A树的节点个数,n是B树的节点个数,遍历A的所有节点O(m),尝试将A的每个节点都作为根去作匹配工作O(n),空间应该是O(m):当树 A和树 B 都退化为链表时,递归调用深度最大。当m≤n 时,遍历树 A 与递归判断的总递归深度为 m ;当 m>n 时,最差情况为遍历至树 A 叶子节点,此时总递归深度为 m:

通过递归调用isSubStructure的方式,遍历A的所有节点去尝试与B匹配,去寻找A中的那个目标根结点;
对于A的每一个以p1为根的子树是不是与B匹配,也用递归isSame的方式去对比;

/**ch
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    //空   空   1
    //空   不空 0
    //不空 空   1
    //不空 不空 递归判断二者的左孩子和右孩子
    bool isSame(TreeNode* p1, TreeNode* p2) {//判断子树p1与子树p2是否匹配
        if (!p2) return true;//空 空 和 不空 空, 即子树p2成功到底
        else if (!p1) return false;//空 不空, 即p2还没匹配完成,主树p1就到底了
        //不空 不空
        else if (p1->val != p2->val) return false; //当前节点已经不匹配
        return isSame(p1->left, p2->left) && isSame(p1->right, p2->right);//当前节点匹配,就去递归判断左右子树都匹配才行
    }
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {//在子树A中寻找一个与子树B匹配的目标根
        if (!A || !B) return false;
        
        if (isSame(A, B)) return true;//目标根是A
        //递归的在A的左右子树中寻找与B匹配的目标根
        return isSubStructure(A->left, B) || isSubStructure(A->right, B);//只要能找到一个目标根即可
    }
};
  • 总结:
    ① 对于树的题,在使用递归时,只需要想清楚当前函数的作用,以及主问题如何分解为子问题即可,不要一直往深处想;
    ② 本题的根节点struct中,根节点值是用int表示的,因此可以直接比较;若用float或double表示的,由于浮点数在计算机中表示时具有不精确性,因此需要专门设计一个equal函数去做比较工作:例如二者误差在0.00000001范围内,就认为它们相等;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值