力扣日常打卡---面试题04.10.检查子树

题目描述:
检查子树。你有两棵非常大的二叉树:T1,有几万个节点;T2,有几万个节点。设计一个算法,判断 T2 是否为 T1 的子树。
如果 T1 有这么一个节点 n,其子树与 T2 一模一样,则 T2 为 T1 的子树,也就是说,从节点 n 处把树砍断,得到的树与 T2 完全相同。
示例:
在这里插入图片描述
在这里插入图片描述
思路与题解:
看到题目要求,这种包含关系,第一时间我想的是把二叉树与字符串进行转换,然后判断:

return !(s1.find(s2)==string::npos);

其中s1为t1树中序遍历的结果,s2为t2树中序遍历的结果,具体遍历过程如下:

void inorder(TreeNode* node,string s)
{
	if(node==nullptr)return;
	inorder(node->left,s);
	s += to_string(node->val);
	inorder(node->right,s);
}

但是,仔细一想,就发现其中的不对,居然力扣上还有人把它当作正确题解发了出来—错误代码我觉得更是大错特错! 如果他能通过测试用例的话,只能说力扣的测试用例不严谨。举两个例子,对于下方的二叉树而言:
在这里插入图片描述
如下的两棵树,进行上述操作后能返回true,但实际结果应该为false:
在这里插入图片描述在这里插入图片描述
所以,正确的解法应该为深度优先搜索(dfs),思路如下:
对 t1 及其左右子树分别用 dfs 算法,若其中一项满足要求则返回true,否则返回false。
具体实现代码如下:

/**
 * 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 {
public:
    bool checkSubTree(TreeNode* t1, TreeNode* t2) {
        if(t1==NULL)return t2==NULL;
        if(t2==NULL)return true;
        return dfs(t1,t2)||checkSubTree(t1->left,t2)||checkSubTree(t1->right,t2);
    }
    bool dfs(TreeNode* t1,TreeNode* t2)
    {
        if((t1==NULL&&t2!=NULL)||(t1!=NULL&&t2==NULL))return false;
        if(t1==NULL&&t2==NULL)return true;
        return (t1->val==t2->val)&&dfs(t1->left,t2->left)&&dfs(t1->right,t2->right);
    }
};

由于dfs最长深度为n,搜寻t1值与t2值的时间也为O(n),但由于C++的短路原则,算法整体时间复杂度为O(n),空间复杂度为O(1),满足题目所述的万节点要求,最终运行评价如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值