26-LeetCode

文章目录



题目

树的子结构。输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如:
给定的树 A:
3
/ \
4 5
/ \
1 2

给定的树 B:
4
/
1

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




法一:递归

  1. 先在A树中找到和B树根节点相同的节点
  2. 找到相同的根节点后,从根节点开始判断A是否包含B树
    • 当B为空,说明B已匹配完成,返回true
    • 当A为空,说明已经超过A叶子节点,即匹配失败,返回false
    • 当节点A和B的值不同,说明匹配失败,返回false

时间复杂度 O(MN)
M:A树的节点数量
N:B树的节点数量


空间复杂度:O(M)
A和B都退化成链表时,递归调用深度最大




代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <list>

using namespace std;

struct TreeNode
{
    int data;
    TreeNode * left;
    TreeNode * right;
    TreeNode(int value)
    {
        data = value;
        left = NULL;
        right = NULL;
    }
};

/*
二叉树的子结构
1:先在A树中找到和B树根节点相同的节点
2:判断A是否包含B树
   2.1:当B为空,说明B已匹配完成,返回true
   2.2: 当A为空,说明已经超过A叶子节点,即匹配失败,返回false
   2.3: 当节点A和B的值不同,说明匹配失败,返回false

时间复杂度 O(MN)
M:A树的节点数量
N:B树的节点数量

空间复杂度:O(M)
A和B都退化成链表时,递归调用深度最大

*/
// 判断A树是否包含B树
bool Judge(TreeNode * A , TreeNode * B)
{
    if(B == NULL)			//2.1:当B为空,说明B已匹配完成,返回true
    {
        return true;
    }
    if(A == NULL)			//2.2: 当A为空,说明已经超过A叶子节点,即匹配失败,返回false
    {
        return false;
    }
    if(A->data == B->data)	//2.3: 当节点A和B的值不同,说明匹配失败,返回false
    {
        return Judge(A->left , B->left) && Judge(A->right , B->right);
    }
}

bool IsSubTree(TreeNode * A , TreeNode * B)
{
    if(A == NULL || B == NULL)
    {
        return false;
    }

    // 判断A当前节点为根节点的是否包含B子树
    if(Judge(A , B))
    {
        return true;
    }
    else
    {
        return IsSubTree(A->left , B) || IsSubTree(A->right , B);
    }
}

int main()
{
    TreeNode root(8);
    TreeNode node1(4);
    TreeNode node2(2);

    TreeNode node3(9);
    TreeNode node4(12);

    TreeNode node5(1);
    TreeNode node6(5);

    root.left = &node1;
    root.right = &node2;

    node1.left = &node3;
    node1.right = &node4;

    node2.left = &node5;
    node2.right = &node6;

    TreeNode subnode(4);
    TreeNode subnode_1(9);
    TreeNode subnode_2(12);
    subnode.left = &subnode_1;
    subnode.right = &subnode_2;

    cout << IsSubTree(&root , &subnode) << endl;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值