面试题33.二叉树的后序遍历序列
题目
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
解题思路
递归思路:依据二叉搜索树的DST后序遍历的性质找出数组中根节点的位置,左子树和右子树的位置
在后序遍历得到的数组中,如
[
a
,
⋯
,
b
,
b
+
1
,
⋯
,
j
−
1
,
j
]
[a,\cdots,b,b+1,\cdots,j-1,j]
[a,⋯,b,b+1,⋯,j−1,j],其中,
j
j
j为根节点,
[
a
,
⋯
,
b
]
[a,\cdots,b]
[a,⋯,b]为左子树,
[
b
+
1
,
⋯
,
j
−
1
]
[b+1,\cdots,j-1]
[b+1,⋯,j−1]为右子树,所以我们找到左右子树,看右子树的所有节点的末节点索引是否为
j
−
1
j-1
j−1判断出是否为后序遍历序列。
- 递归基:只剩一个节点或没有节点不需要判断,返回T
- 递归处理:
- 根节点为区间的最后一个节点,由此找到左子树的所有节点的末节点的索引
- 查找右子树的末端节点看是否为j-1,若不是则说明有节点不应位于右子树,因此返回False
- 深入左子树DFS(i,endIdx)和右子树DFS(endIdx+1,j-1)看是否满足要求
code1:使用索引的写法1
class Solution:
def verifyPostorder(self, postorder: List[int]) -> bool:
#递归思路:依据BST后序遍历的性质找出数组中根节点的位置,左子树和右子树的位置
def DFS(i,j):#对区间[i,j]进行判断
if i >= j: return True#递归基:只剩一个节点或没有节点不需要判断,返回T
#根节点为区间的最后一个节点,由此找到左子树的所有节点的末节点的索引
idx = i
while postorder[idx]<postorder[j]:
idx += 1
endIdx = idx-1#左子树的所有节点的末节点索引
#查找右子树的末端节点看是否为j-1,若不是则说明有节点不应位于右子树,因此返回False
while postorder[idx]>postorder[j]:
idx += 1
if idx != j:return False
return DFS(i,endIdx) and DFS(endIdx+1,j-1)#深入左子树和右子树看是否满足要求
return DFS(0,len(postorder)-1)
code2:使用分片写法2
class Solution:
def verifyPostorder(self, postorder: List[int]) -> bool:
#递归思路:依据二叉搜索树DST后序遍历的性质找出数组中根节点的位置,左子树和右子树的位置
def DFS(nums):#判断[i,j]区间是否满足二叉搜索树的要求
if len(nums)<2: return True
root = nums[-1]
idx = 0
while nums[idx] < root:
idx += 1
leftEnd = idx
while nums[idx] > root:
idx += 1
if idx != len(nums)-1: return False
return DFS(nums[:leftEnd]) and DFS(nums[leftEnd:-1])
return DFS(postorder)