LeetCode 二叉搜素树的后序遍历序列

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

参考以下这颗二叉搜索树:
在这里插入图片描述

示例 1:

输入: [1,6,3,2,5]
输出: false
示例 2:

输入: [1,3,2,6,5]
输出: true

提示:

数组长度 <= 1000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof

思路:
我们都知道,二叉树的后序遍历,先访问左子树,然后是右子树,最后是自身这个节点。所以根节点必定是在序列的最后。
基于这个特点,我们的解题思路:
1、获取根节点root,对应的下标是high
2、在root这个数之前找到第一个大于等于root的数,并标记它的下标为index,从而将数组分成两个子数组,[0,index - 1],[index,high - 1],其中理论上[0,index - 1]是root的左子树,[index,high - 1]是root的右子树
3、由二叉搜索树的定义,我们需要判断[index,high - 1]是否都是大于等于root的数,如果其中含有一个数小于root,说明这个序列不是二叉搜索树的后序遍历序列,返回false,否则,如果符合了,那么就进入递归,判断这两个子树是否符合。

对应的代码:

class Solution {
    public boolean verifyPostorder(int[] postorder) {
         return judge(postorder,0,postorder.length - 1);
    }
    public boolean judge(int[] postOrder,int low,int high){
        if(low < high){
           int root = postOrder[high];//获取根节点的值
           //遍历数组,从而找到第一个大于等于根节点的数,从而将子数组分成两个子数组
           int index = findElement(postOrder,low,high - 1,root);
           if(index != -1) {
               /*
               index等于-1,说明都是小于根节点的值,那么只需要对这一部分进
               行判断即可,即判断这一个子树即可,否则需要划分成两个子数组,
               分别对两个子数组进行相应的判断,如果两个子数组符合要求,那
               么在进行相应的递归否则直接返回false。
               但是由于在上面调用findElement方法找到第一个大于root的值,
               那么就已经判断了左子树[low,index - 1]是明显都是小于root的
               数,即符合左子树的节点的数都是小于root的数,所以只需要判断
               右子树即可
               */
               boolean flag = isRight(postOrder,index,high - 1,root);
               return flag && judge(postOrder,low,index - 1) && judge(postOrder,index,high - 1);
           }
           return judge(postOrder,low,high - 1); //在数组都是小于根节点的时候,判断它的左子树是否符合二叉搜索树要求
           
        }else{
        //如果没有节点了,那么直接返回true
            return true;
        }
        
    }
    //判断当前数组是否是root的右子树
    public boolean isRight(int[] postOrder,int low,int high,int root){
        while(low <= high){
            if(postOrder[low] < root)
               return false;
            low++;
        }
        return true;
    }

    public int findElement(int[] postOrder,int low,int high,int root){
        while(low <= high){
           if(postOrder[low] >= root)
               return low;
            low++;
        }
        return -1;//返回-1的时候,说明都是小于root的数
    }
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于一棵后序遍历,我们首先遍历左子,然后遍历右子,最后访问根节点。根据这个顺序,我们可以借助一个栈来完成。 假设要输出根节点root到某一结点target的路径,首先,我们将root节点入栈。然后,进行以下循环: 1. 将栈顶节点弹出; 2. 如果栈顶节点的值等于target的值,则说明找到了目标结点,结束循环; 3. 如果栈顶节点的右子不为空且右子未被访问过,则将右子入栈; 4. 如果栈顶节点的左子不为空且左子未被访问过,则将左子入栈; 5. 如果栈顶节点的左右子都为空,说明该结点是叶子节点,将其出栈。 最终,栈中保存的结点序列就是根节点到目标结点的路径。 下面是一个示例代码,假设的节点定义如下: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None ``` ```python def postorderPath(root, target): if root is None: return [] stack = [] result = [] visited = set() stack.append(root) while stack: node = stack[-1] if node in visited: stack.pop() result.pop() else: visited.add(node) result.append(node.val) if node.val == target: break if node.right and node.right not in visited: stack.append(node.right) if node.left and node.left not in visited: stack.append(node.left) return result ``` 这样,调用`postorderPath(root, target)`函数即可得到根节点root到目标结点target的路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值