剑指offer17_树的子结构_题解

树的子结构

题目描述

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

示例1

输入

{8,8,#,9,#,2,#,5},{8,9,#,2}

返回值

true

分析

方案一:递归

dfs(A, B)函数
  1. 终止条件:
    • 当树 \(B\) 为空:说明 \(B\) 已匹配完成,因此返回 \(true\)
    • 当树 \(A\) 为空,树 \(B\) 不为空:说明已经越过 \(A\) 的叶子节点,返回 \(false\)
    • 当节点 \(A\)\(B\) 的值不同:说明匹配失败,返回 \(false\)
  2. 返回值:
    • 判断 \(A\)\(B\) 的左子节点是否相等,即 \(dfs(A->left, B->left)\)
    • 判断 \(A\)\(B\) 的左子节点是否相等,即 \(dfs(A->right, B->right)\)
HasSubtree(A, B)函数
  1. 特例处理:当树 \(A\) 为空或树 \(B\) 为空时,直接返回 \(false\)
  2. 返回值:若树 \(B\) 是树 \(A\) 的子结构,则满足以下三种情况之一
    • 以节点 \(A\) 为根节点的子树包含树 \(B\)
    • \(B\) 是树 \(A\) 左子树的子结构
    • \(B\) 是树 \(A\) 右子树的子结构
/**
时间复杂度:O(n)
空间复杂度:O(1)
**/
class Solution
{
public:
    bool dfs(TreeNode *r1, TreeNode *r2)
    {
        // 如果树B为空,说明B已匹配完成,因此返回true
        if (!r2)
            return true;
        // 如果树B不为空,但是树A为空,说明已经越过A的叶子节点,返回false
        if (!r1)
            return false;
        // 如果树A的根节点和树B的根节点值不相等,直接返回false
        // 否则相等,继续判断A的左子树和B的右子树
        return r1->val == r2->val && dfs(r1->left, r2->left) && dfs(r1->right, r2->right);
    }

    bool HasSubtree(TreeNode *pRoot1, TreeNode *pRoot2)
    {
        // 特判树为空的情况
        if (!pRoot1 || !pRoot2)
            return false;
        // 1.以节点A为根节点的子树包含树B
        // 2.树B是树A左子树的子结构
        // 3.树B是树A右子树的子结构
        return dfs(pRoot1, pRoot2) || HasSubtree(pRoot1->left, pRoot2) || HasSubtree(pRoot1->right, pRoot2);
    }
};
posted @ 2020-12-14 22:22  RiverCold  阅读(50)  评论(0编辑  收藏  举报