算法学习记录十三(C++)--->10年微软面试题树的子结构

描述

输入两棵二叉树A和B,判断树B是不是A的子结构。

分析

例如,下图中的两棵树A和B,由于A中有一部分子树的结构和B是一样的,因此B就是A的子结构。
这里写图片描述

第一步:找到相同根节点
第二步:找到相同根节点后匹配左右子树是否值都匹配

代码 (复杂flag版本但是思路很清晰)

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
/*
class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool flag = false;
        // 当两棵树都不为空的时候进行匹配
        if(!pRoot1 == NULL && !pRoot2 == NULL){
            if(pRoot1->val == pRoot2->val){
                // 当根节点相同的时候进行判断是否包含
                flag = tree2ContainerTree1(pRoot1,pRoot2);
            }
            // 如果上面根节点不同,那么flag是no  或者根节点相同而且对应的flag匹配失败,还是no
            if(!flag){
                flag = HasSubtree(pRoot1->left,pRoot2);
            }
            // 如果左子树未匹配到,那么进行右子树匹配
            if(!flag){
                flag = HasSubtree(pRoot1->right,pRoot2);
            }
        }
        return flag;
    }

    // 判断是否被包含
    bool tree2ContainerTree1(TreeNode *node1, TreeNode *node2){
        // 当node2的树遍历完的时候就是被包含的
        if(node2 == NULL){
            return true;
        }
        // 当node1的树提前结束,node2没结束,肯定不包含
        if(node1 == NULL){
            return false;
        }
        // 当某个节点不同的时候 不包含
        if(node1->val != node2->val){
            return false;
        }
        // 如果根节点都对的上,那么继续用子节点进行匹配,左右都匹配到的时候才算被包含
        return tree2ContainerTree1(node1->left,node2->left) && tree2ContainerTree1(node1->right,node2->right);
    }
};
*/

代码(精简版本)

class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        if(pRoot1 == NULL || pRoot2 == NULL)return false;
        return tree2ContainerTree1(pRoot1,pRoot2) ||
            HasSubtree(pRoot1->left,pRoot2) ||
            HasSubtree(pRoot1->right,pRoot2);
    }

    // 判断是否被包含
    bool tree2ContainerTree1(TreeNode *node1, TreeNode *node2){
        if(node2 == NULL) return true;
        if(node1 == NULL) return false;
        if(node1->val == node2->val){
            return tree2ContainerTree1(node1->left,node2->left) && tree2ContainerTree1(node1->right,node2->right);
        }else{
            return false;
        }
    }
};


1.真的|| 运算符,C的特性就是当某一个为真的时候就不会继续向下运行,因此不会有过多的运算
2.tree2ContainerTree1 该方法是当根节点一致的时候,左右子树是否一致,当node2为空的时候 就是被包含了,如果node1提前为空,而node2还不为空,肯定不包含了,递归向左右进行节点判断
3.HasSubtree 当根节点一致的时候,就去调用tree2ContainerTree1 进行包含判断,但是如果不等,递归HasSubtree 进行匹配,直到节点相同进行包含判断,否则的话就是不包含

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值