题目大意
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例1
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
解题思路
- 通过前序遍历结果弹栈作为root节点, 根据中序遍历结果划分左子树和右子树
- 如何判断所给的前序遍历结果和中序遍历结果是对应的
方法1: 递归求解
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
if inorder:
idx = inorder.index(preorder.pop(0))
root = TreeNode(inorder[idx])
root.left = self.buildTree(preorder, inorder[:idx])
root.right = self.buildTree(preorder, inorder[idx+1:])
return root
上述代码不具备检测非法输入的能力, 需要补充的逻辑很简单: 前序遍历结果弹栈之后, 判断这个值是否在中序遍历结果中, 没有的话, 提示非法输入(C++中是对中序遍历结果从头开始遍历, 如果找到尾都没找到这个值, 则输入非法)
#include <iostream>
#include <cstdio>
using namespace std;
struct BinaryTreeNode
{
int value;
BinaryTreeNode* left;
BinaryTreeNode* right;
};
BinaryTreeNode* Construct(int* preorder, int* inorder, int length)
{
if(preorder == NULL || inorder == NULL || length <= 0)
return NULL;
return ConstructCore(preorder, preorder + length - 1,
inorder, inorder + length - 1);
}
BinaryTreeNode* ConstructCore
(
int* startPreorder, int* endPreorder,
int* startInorder, int* endInorder
)
{
// 前序遍历序列的第一个数字是根节点的值
int rootValue = startPreorder[0];
BinaryTreeNode* root = new BinaryTreeNode();
root->value = rootValue;
root->left = root->right = NULL;
if(startPreorder == endPreorder)
{
if(startInorder == endInorder
&& *startPreorder == *startInorder)
return root;
else
// 判断输入是否合法
throw std::exception("Invalid input.")
}
// 在中序遍历中找到跟节点的值
int* rootInorder = startInorder;
while(rootInorder <= endInorder && *rootInorder != rootValue)
++ rootInorder;
if(rootInorder == endInorder && *rootInorder != rootValue)
throw std::exception("Invalid input."); // 如果遍历Inorder最后都没有对应的跟节点,则视为无效输入
int leftLength = rootInorder - startInorder;
int* leftPreorderEnd = startPreorder + leftLength;
if(leftLength > 0)
{
// 构建左子树
root->left = ConstructCore(startPreorder + 1,
leftPreorderEnd, startInorder, rootInorder - 1);
}
if(leftLength < endPreorder - startPreorder)
{
// 构建右子树
root->right = ConstructCore(leftPreorderEnd + 1,
endPreorder, rootInorder + 1, endInorder);
}
return root;
}
标签:preorder,遍历,07,Offer,int,root,中序,二叉树,inorder
From: https://www.cnblogs.com/mujuna/p/16595393.html