博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
力扣题解-106. 从中序与后序遍历序列构造二叉树(分治法思想,递归的方式求解)
阅读量:4300 次
发布时间:2019-05-27

本文共 2536 字,大约阅读时间需要 8 分钟。

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

根据一棵树的中序遍历与后序遍历构造二叉树。

注意:

你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7]

后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:

3   / \  9  20    /  \   15   7

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

后序遍历序列的最后一个元素即为根节点。

中序遍历序列的根节点位于中间,左边为其左子树构成的中序遍历序列,右边为其右子树构成的中序遍历序列。

根据左右子树的序列长度,就可以确定后序遍历序列的左右子树序列的分界点。

举例来说明分治法思想的运用。

中序遍历 inorder = [9,3,15,20,7]

后序遍历 postorder = [9,15,7,20,3]

  1. divide
    首先找出根节点,即postorder的元素3;然后找到元素3在inorder的位置,将inorder序列分为左子树序列 [9] 和右子树序列 [15,20,7];

此时根据inorder的左子树序列可以确定,将postorder分为左子树序列 [9] 和右子树序列 [15,7,20];

  1. conquer

    构造根节点root(3),然后递归地处理左子树序列和右子树序列,分别作为左子树left和右子树right。

  2. combine

    将二叉树拼接起来,即root->left = left,root->right = right, 返回root。

代码

/** * 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 {
vector
inorder; vector
postorder;public: TreeNode* buildTree(vector
& inorder, vector
& postorder) {
this->inorder = inorder; this->postorder = postorder; return dfs(0, inorder.size()-1, 0, postorder.size()-1); } TreeNode* dfs(int startIn, int endIn, int startPost, int endPost) {
if (startPost > endPost or startIn > endIn) {
return NULL; } if (startPost == endPost or startIn == endIn) {
return new TreeNode(postorder[startPost]); } TreeNode * root = new TreeNode(postorder[endPost]); int rootPos = findRootPosInorder(postorder[endPost], startIn, endIn); if (rootPos < 0) {
return NULL; } int leftStartIn = startIn; int leftEndIn = rootPos-1; int rightStartIn = rootPos+1; int rightEndIn = endIn; int leftSize = rootPos-startIn; int leftStartPost = startPost; int leftEndPost = startPost + leftSize-1; int rightStartPost = startPost + leftSize; int rightEndPost = endPost-1; root->left = dfs(leftStartIn, leftEndIn, leftStartPost, leftEndPost); root->right = dfs(rightStartIn, rightEndIn, rightStartPost, rightEndPost); return root; } int findRootPosInorder(int value, int startIn, int endIn) {
for (int i = startIn; i <= endIn; i++) {
if (value == inorder[i]) {
return i; } } return -1; }};
你可能感兴趣的文章
Java数据结构和算法-2-数组-自定义封装一个数组操作类(2)
查看>>
Java数据结构和算法-3-数组-简单排序:冒泡排序/选择排序/插入排序
查看>>
Java数据结构和算法-4-栈和队列-封装一个自定义栈和队列类并提供相关类方法
查看>>
Java数据结构和算法-5-单链表方法
查看>>
Jenkins高级篇之Pipeline技巧篇-1-小白搭建Pipeline项目开发环境
查看>>
Jenkins高级篇之Pipeline技巧篇-2-如何处理多个参数化变量
查看>>
Jenkins高级篇之Pipeline技巧篇-3-JSON文件处理多个参数进一步优化
查看>>
Jenkins高级篇之Pipeline技巧篇-4-根据参数传入条件控制执行不同stage
查看>>
Jenkins高级篇之Pipeline技巧篇-5-pipeline中如何代码串联多个job的执行
查看>>
Jenkins高级篇之Pipeline技巧篇-6-pipeline中使用jenkins share lib 方法
查看>>
JavaWeb学习-JDBC系列-1-JDBC概述
查看>>
JavaWeb学习-JDBC系列-2-JDBC4个核心对象基本代码
查看>>
JavaWeb学习-JDBC系列-3-DriverManager介绍
查看>>
JavaWeb学习-JDBC系列-4-Statement介绍
查看>>
JavaWeb学习-JDBC系列-5-ResultSet介绍
查看>>
JavaWeb学习-JDBC系列-6-释放资源的正确代码方式
查看>>
JavaWeb学习-JDBC系列-7-封装一个DB工具类
查看>>
JavaWeb学习-JDBC系列-8-基于DBUtils工具类的CRUD练习
查看>>
JavaWeb学习-JDBC系列-9-基于JDBC做一个登陆练习
查看>>
JavaWeb学习-JDBC系列-10-SQL注入问题和PreparedStatement对象
查看>>