Python3-[32]面试题33.二叉树的后序遍历序列(后序遍历/DFS)

题目

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

解题思路

递归思路:依据二叉搜索树的DST后序遍历的性质找出数组中根节点的位置,左子树和右子树的位置
在后序遍历得到的数组中,如 [ a , ⋯   , b , b + 1 , ⋯   , j − 1 , j ] [a,\cdots,b,b+1,\cdots,j-1,j] [a,,b,b+1,,j1,j],其中, j j j为根节点, [ a , ⋯   , b ] [a,\cdots,b] [a,,b]为左子树, [ b + 1 , ⋯   , j − 1 ] [b+1,\cdots,j-1] [b+1,,j1]为右子树,所以我们找到左右子树,看右子树的所有节点的末节点索引是否为 j − 1 j-1 j1判断出是否为后序遍历序列。

  • 递归基:只剩一个节点或没有节点不需要判断,返回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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值