技巧:
前中后序迭代基础上递归构建树
思路:
【 若某节点只有一个子结点,则此处将其看作左儿子结点】 如果没这个条件是有歧义的 如下图 中序都是2,1 无法构建唯一树
1 1
/ \
2 2
先序遍历 根左右
后续遍历 左右根
这类题目要搞清楚 =》 左子树是哪一段? 右子树是哪一段?
计先序数组遍历结果叫做pre 后续数组遍历结果叫做suf 。 pl pr sl sr 代表当前的pre数组头尾指针和suf数组头尾指针 pos代表先序左孩子在suf的位置
(左子树是范围在suf数组中sl - pos里面, 根据后续遍历的特性,右子树范围夹在了suf数组 根(sr)和左(pos)之间 )
差值个数 =》 pos - sl + 1
LEFT : pre 取值 【pl + 1, pl + 差值个数】 suf 取值【sl, pos】
RIFHT: pre 取值 【 pl + 差值个数 + 1, pr】 suf 取值【pos + 1, sr - 1】
实现:
package main /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int 二叉树节点数量 * @param pre int一维数组 前序序列 * @param suf int一维数组 后序序列 * @return int一维数组 */ func solve( n int , pre []int , suf []int ) []int { return midPrint(pre, 0, n-1, suf, 0, n-1, make([]int,0)) } // 左边是pre.next // 右边是 2和1中间夹着的(左右中 中间活该被夹着) func midPrint(pre []int, pl, pr int, suf []int, sl, sr int, resultSet []int) []int{ if pl == pr { return append(resultSet, pre[pl]) } if pl < pr { // 找到左孩子index (左右划分比较点) leftChlidPos := 0 for pre[pl + 1] != suf[leftChlidPos] { leftChlidPos ++ } resultSet = midPrint(pre, pl + 1, pl + (leftChlidPos - sl + 1), suf, sl, leftChlidPos, resultSet) resultSet = append(resultSet, pre[pl]) resultSet = midPrint(pre, pl + (leftChlidPos - sl + 1) + 1, pr , suf, leftChlidPos + 1, sr - 1, resultSet) } return resultSet }