剑指 Offer 33. 二叉搜索树的后序遍历序列(中等)

这篇博客介绍了如何通过深度优先搜索(DFS)和单调栈两种方法来验证给定的数组是否符合后序遍历的顺序。在DFS方法中,重点在于递归边界条件和分治策略;而在单调栈方法中,利用栈的性质快速检查元素顺序。这两种方法的时间复杂度和空间复杂度各有不同,DFS可能达到O(N^2),而单调栈则是O(N)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

此题只是判断数组是否符合条件,只需要判断数组即可,不用返回数组

方法一:深度优先搜索(递归)

方法二:单调栈

 

代码:

方法一:

class Solution {
    public boolean verifyPostorder(int[] postorder) {
		return dfs(postorder,0,postorder.length-1);
		
    }
	
	private boolean dfs(
				int[] postorder,
				int i,
				int j
	){
		//注意边界,是"="
		if(i>=j){
			return true;
		} 
		
		int p=i;
		while(postorder[p]<postorder[j]){
			p++;
		}
		
		int m=p;
		while(postorder[p]>postorder[j]){
			p++;
		}
		
		//第一个:是i而不是0
		//第二个:根不是j,所以是j-1
		return p==j&&dfs(postorder,i,m-1)&&dfs(postorder,m,j-1);
	}
}

方法二:

class Solution {
    public boolean verifyPostorder(int[] postorder) {
		Deque<Integer> stack=new ArrayDeque<>();
		int root=Integer.MAX_VALUE;
		for(int i=postorder.length-1;i>=0;i--){
			if(postorder[i]>root){
				return false;
			}
			while(!stack.isEmpty()&&postorder[i]<stack.peekLast()){
				root=stack.removeLast();
			}
			stack.addLast(postorder[i]);
		}
		return true;
	}
}

 

分解:

1)方法一:

    i)注意边界,是"i>=j"而不是"i>j"

    ii)递归时,有三个项:

         1.判断p==j,表明每次都搜寻完了

         2.左边递归(i,m-1),注意是i而不是0

         3.右边递归(m,j-1),注意是j-1而不是j

整个过程是:最后一个是根节点,根节点左边都小于根节点,根节点右边都大于根节点

                      利用一个变量标记左右节点的转换点

 

2)方法二:

利用后序遍历倒序和一个单调栈。

注意每次while循环体都是把一整个当前情况的树节点都弹出,使得单调栈能用于下一个情况

 

复杂度分析:

方法一:

    i)时间复杂度:O(N^2) 每次递归的时间复杂度都是O(N),最差情况下每次都要搜索到最后一个

    ii)空间复杂度:O(N) 最差情况下是一个链表,递归的深度为节点数N

 

方法二:

    i)时间复杂度:O(N) 每个节点都加入、弹出单调栈一次

    ii)空间复杂度:O(N) 额外空间是一个单调栈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值