解答:
前序遍历:中左右
中序遍历:左中右
后序遍历:中右左
根据 前序 可以确定root,然后在中序中可以找到 左右 子树范围。
进一步递归即可找到所有点。
代码:
class Node:
def __init__(self,value):
self.value = value
self.left = None
self.right = None
self.parent = None
def show_all(self):
print(self.value)
#print(self.left,'###')
#print(self.right,'???')
if self.left:
print('left of %d :'%self.value)
self.left.parent = self
self =self.left
self.show_all()
self = self.parent
if self.right:
print('right of %d :'%self.value)
self.right.parent = self
self = self.right
#print('right')
self.show_all()
class Solution:
def reconstruct(self,arr1,arr2):
global tree
tree = Node(0)
self.construct(arr1,arr2,tree,'l')
return tree.left
def construct(self,arr1,arr2,tree_node,direction):
#print(arr1,arr2,direction)
root = arr1[0]
node = Node(root)
if direction == 'l':
#print('LLLLL')
tree_node.left = node
else:
#print('RRRRRR')
tree_node.right = node
#print(arr2,root)
x = arr2.index(root)
left2 = arr2[:x]
l_l = len(left2)
right2 = arr2[x+1:]
#l_r = len(right2)
left1 = arr1[1:1+l_l]
right1 = arr1[1+l_l:]
#print(left1,left2,'arr1')
#print(right1,right2,'arr2')
if left1 :
self.construct(left1,left2,node,'l')
if right1 :
self.construct(right1,right2,node,'r')
su = Solution()
arr1 = [1,2,4,7,3,5,6,8]
arr2 = [4,7,2,1,5,3,8,6]
res = su.reconstruct(arr1,arr2)
print(res)
res.show_all()
tips:
1 初始化node,带初始化方法以及 全部显示方法。
2 带入递归时,初始化一个0点,将其导入进行连接。最后返回其left。
3 根据导入的direction确定 正在处理的该点root 连接在哪个子点上。
4 寻找对应的左右子树 的 前序 和 中序
5 打印节点时,做一个parent的属性,这样在左子点使用以后 返回 便于 右子点继续使用。
面试题33. 二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
5
/ \
2 6
/
1 3
示例 1:
输入: [1,6,3,2,5]
输出: false
示例 2:
输入: [1,3,2,6,5]
输出: true
解答:
一开始我的想法是,BST的左右子树的大小排序应该满足条件即可。
1 末尾为 root
2 一旦出现大于root的值,则此处开始为右子树,左小右大即可
如此判断即可。(没有考虑到剩下树的情况)
应该添加:
3 对分离的左右子树继续递归操作:
1) 如果为空则返回True
2) 如果不为空,取根节点然后继续上面的判定
3) 添加跳出递归的情况:当出现不满足左小右大的情况则跳出
此题与上面的比较类似,都是通过树的本身规律做递归找到左右子树然后进行判定。