7.24树题目整理

出处:剑指offer07

题目:输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

思路:前序遍历:中左右,中序遍历:左中右。前序遍历的第一个结点就是根结点,通过根结点对中序遍历进行划分得到左子树和右子树,分别递归对其他结点也进行这样的递归得到划分后的二叉树。

注意点:对于前、中、后序遍历的划分如下所示:

//已知前中构造
TreeNode* build(vector<int>& preorder, vector<int>& inorder, int pre_start, int pre_end, int in_start, int in_end)
{
    if (pre_start > pre_end)return nullptr;
    if (in_start > in_end)return nullptr;
    int val = preorder[pre_start];
    TreeNode* root = new TreeNode(val);
    int k;
    for (k = 0; k <= in_end; k++)
    {
        if (preorder[pre_start] == inorder[k])
            break;
    }
    int len = k - in_start;
    root->left = build(preorder, inorder, pre_start + 1, pre_start + len + 1, in_start, k - 1);
    root->right = build(preorder, inorder, pre_start + len + 1, pre_end, k + 1, in_end);
    return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
    int pre_start = 0, pre_end = preorder.size() - 1;
    int in_start = 0, in_end = preorder.size() - 1;
    return build(preorder, inorder, pre_start, pre_end, in_start, in_end);
}

 已知中序和后序重建二叉树:


//已知中后构造
TreeNode* build(vector<int>& inorder, vector<int>& postorder, int inorder_start, int inorder_end, int postorder_start, int postorder_end)
{
    if (postorder_start > postorder_end)
        return nullptr;
    int val = postorder[postorder_end];
    TreeNode* root = new TreeNode(val);
    int k = 0;
    for (k = 0; k <= inorder_end; k++)
    {
        if (postorder[postorder_end] == inorder[k])
        {
            break;
        }
    }
    int len = k - inorder_start;//更新后左节点个数
    root->left = build(inorder, postorder, inorder_start, k - 1, postorder_start, postorder_start + len - 1);
    root->right = build(inorder, postorder, k + 1, inorder_end, postorder_start + len, postorder_end - 1);
    return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
    int inorder_start = 0, inorder_end = inorder.size() - 1;
    int postorder_start = 0, postorder_end = postorder.size() - 1;
    return build(inorder, postorder, inorder_start, inorder_end, postorder_start, postorder_end);

}

出处:剑指offer026

题目:

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

思路:

递归三步求解

1.返回值:返回是否是子结构

2.终止条件:如果递归时A(大树)为空返回false,B(子结构)空返回true。

3.单步递归逻辑:当A,B结点中的值相同时,同时判断func(A->left,B)||func(A->right,B) B是否存在与A的左子树或右子树中。

    bool isSubStructure(TreeNode* A, TreeNode* B) 
    {
        if(!A||!B)return false;
        if(A->val==B->val&&check(A->left,B->left)&&check(A->right,B->right))
        {
            return true;
        }
        return isSubStructure(A->left,B)||isSubStructure(A->right,B);
    }
    bool check(TreeNode* A, TreeNode* B)
    {
        if(!B)
            return true;
        if(!A)
            return false;
        if(A->val==B->val)
            return check(A->left,B->left)&&check(A->right,B->right);
        else
            return false;
    }

出处:剑指offer27

题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。

 思路:后序遍历,递归

1.返回:输出镜像树的根节点

2.终止条件:当结点为null时返回null

3.单步逻辑:后序遍历拿到中结点的左右子结点,交换两个结点。

    TreeNode* mirrorTree(TreeNode* root) 
    {
        if(!root)
            return NULL;
        mirrorTree(root->left);
        mirrorTree(root->right);
        TreeNode *left=root->left;
        TreeNode *right=root->right;  
        root->left=right;
        root->right=left;
        return root;
    }

出处: 剑指offer28

题目:判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

思路:二叉树对称要求左子树的左结点等于右子树的右结点,并且左子树的右节点等于右子树的左结点

参考:力扣

递归

1.返回值:返回bool

2.终止条件:如果root1&&root2则返回true,如果root1或root2有一个为null或当前结点值不相同返回false

3.单步逻辑:返回func(A->left,B->right)&&func(A->right,B->left)

    bool check(TreeNode* root1, TreeNode* root2)
    {
        //终止条件
        if (root1 == NULL && root2 == NULL)return true;
        else if (root1 == NULL && root2 != NULL)return false;
        else if (root1 != NULL && root2 == NULL)return false;
        //单层递归
        if (root1->val != root2->val)return false;
        bool flag1=check(root1->left, root2->right);
        bool flag2=check(root1->right, root2->left);
        bool isSame = flag1 && flag2;
        return isSame;
    }

    bool isSymmetric(TreeNode* root) 
    {
        if (root==NULL)
            return true;
        else return check(root->left,root->right);

    }

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值