• 从中序遍历和后序遍历构建二叉树


    题目描述

    106. 从中序与后序遍历序列构造二叉树

    中等

    1.1K

    相关企业

    给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

    示例 1:

    输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
    输出:[3,9,20,null,null,15,7]
    

    示例 2:

    输入:inorder = [-1], postorder = [-1]
    输出:[-1]
    

    提示:

    • 1 <= inorder.length <= 3000
    • postorder.length == inorder.length
    • -3000 <= inorder[i], postorder[i] <= 3000
    • inorder 和 postorder 都由 不同 的值组成
    • postorder 中每一个值都在 inorder 中
    • inorder 保证是树的中序遍历
    • postorder 保证是树的后序遍历

    思路讲解

    后续遍历:左 右 中

    中序遍历:左 中 右

    假设没有重复值的节点 如果有那就不会是种二叉树 你可以将重复节点挨个遍历 依次确定所有二叉树

    那么后续排序就可以确定这颗二叉树的根节点 再在中序排序中找到该值(根节点)

    将中序遍历分为三部分 左子树的中序遍历 根节点 右子树的中序遍历 

    将后序遍历分为三部分 左子树的后续遍历 右子树的后续遍历 根节点

    经过上面的处理 不能形成一颗完整的二叉树 因为里面有左右子树还没有确定其根节点

    那么就要再进行上 面的操作 直到将左右子树全部确定完毕 

    需要递归进行处理 也可以模拟递归 用栈去模拟递归 

    结合上面思路先大致想一想递归代码的实现

    代码部分处理

    1. /**//树的节点
    2. * Definition for a binary tree node.
    3. * struct TreeNode {
    4. * int val;
    5. * TreeNode *left;
    6. * TreeNode *right;
    7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
    8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
    10. * };
    11. */
    12. class Solution {
    13. public:
    14. TreeNode* func1(vector<int>& inorder,vector<int>& postorder)//递归
    15. {
    16. //postorder.size()==inorder.size()
    17. if(postorder.size()==0)
    18. {
    19. return nullptr;
    20. }
    21. int val = postorder[postorder.size()-1];
    22. TreeNode* root = new TreeNode(val);//创建节点
    23. int index = 0;//寻找中序的根节点
    24. for(;indexsize();index++)
    25. {
    26. if(inorder[index]==val)
    27. {
    28. break;
    29. }
    30. }
    31. //postorder.size()==inorder.size()
    32. if(postorder.size()==1)
    33. {
    34. return root;
    35. }
    36. postorder.resize(postorder.size()-1);
    37. //左闭右开区间 区间端点就是函数参数
    38. vector<int> leftinorder(inorder.begin(),inorder.begin()+index);
    39. vector<int> rightinorder(inorder.begin()+index+1/*+1就是将中序的根节点舍弃掉*/,inorder.end());
    40. vector<int> leftpostorder(postorder.begin(),postorder.begin()+leftinorder.size());
    41. vector<int> rightpostorder(postorder.begin()+leftinorder.size(),postorder.end());
    42. //递归调用
    43. root->left=func1(leftinorder,leftpostorder);
    44. root->right=func1(rightinorder,rightpostorder);
    45. return root;
    46. }
    47. TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    48. if(inorder.size()==0||postorder.size()==0)//特殊条件的判断
    49. {
    50. return nullptr;
    51. }
    52. return func1(inorder,postorder);
    53. }
    54. };

    递归调用部分:

    需要对递归有一点了解 不然你就在纸上走读代码 去画递归展开图

    调用左树就执行到底之后再进左树调用中的右树调用 再进右树调用还是先执行左树调用再执行右树调用 因为左树调用在右树调用的前面

  • 相关阅读:
    前后端分离项目(十):实现"改"功能(前后端)
    安全性和合规性:保障企业数据的安全
    ArkTS - HarmonyOS服务卡片(创建)
    Postman的高级用法—Runner的使用​
    【网络协议】聊聊UDP协议
    React有slot吗?
    java设计实现10位纯数字短id工具类【从浅入深,保姆级】
    非常经典的一道SQL报错注入题目[极客大挑战 2019]HardSQL 1(两种解法!)
    JUC系列(六) 线程池
    Docker | 镜像浅析,以及制作自己的镜像
  • 原文地址:https://blog.csdn.net/2201_75324712/article/details/133281045