本文已参与「新人创作礼」活动,一起开启掘金创作之路。
从前序与中序遍历序列构造二叉树
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]
提示:
- 1 <= preorder.length <= 3000
- inorder.length == preorder.length
- -3000 <= preorder[i], inorder[i] <= 3000
- preorder 和 inorder 均 无重复 元素
- inorder 均出现在 preorder
- preorder 保证 为二叉树的前序遍历序列
- inorder 保证 为二叉树的中序遍历序列
解题思路
先序遍历的首元素,即为二叉树的root节点。
中序遍历中在root节点之前的元素,为root节点的左子树,在root之后的即为右子树。
步骤:
- 先从先序遍历找到root节点
- 在中序遍历中找到root节点,左侧为左子树,右侧为右子树
- 将先序遍历和中序遍历分别拆为两个数组,递归调用函数
注意计算左右子树的size;
左子树的size = i,即为在中序遍历中,root的index
右子树的size = count - i - 1,即总个数减去左子树的个数,再减去根节点。
代码实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/*
先序遍历的首元素,即为二叉树的root节点。
中序遍历中在root节点之前的元素,为root节点的左子树,在root之后的即为右子树。
步骤:
1. 先从先序遍历找到root节点
2. 在中序遍历中找到root节点,左侧为左子树,右侧为右子树
3. 将先序遍历和中序遍历分别拆为两个数组,递归调用函数
*/
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
if (preorderSize == 0) return NULL;
// 申请空间
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
// 获取到根节点
root->val = preorder[0];
root->left = NULL;
root->right = NULL;
// 遍历中序数组,找到根节点
int i = 0;
while (root->val != inorder[i++]){}
// 退回一位
i--;
// 左子树
// 下一个先序遍历数组
int *next_preorder_left = preorder + 1;
// 下一个中序遍历数组
int *next_inorder_left = inorder;
// 数组个数都为i
root->left = buildTree(next_preorder_left,i, next_inorder_left, i);
// 右子树
int *next_preorder_right = preorder + i + 1;
int *next_inorder_right = inorder + i + 1;
// 右子树个数
int right_count = preorderSize - i - 1;
root->right = buildTree(preorder+1+i, right_count, next_inorder_right, right_count);
return root;
}