【剑指offer】面试题33-二叉搜索树的后序遍历序列

题目

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

样例1
input:7,4,6,5
outpu:false
样例2
input:2,4,3,6,8,7,5
output:true

解题思路

二叉搜索树的特点,左子树中结点的值小于根结点的值,右子树中结点的值大于根结点的值。
思路1 递归
后序遍历的特点,序列的最后一个元素是当前树的“根结点”。
所以每次先在最后找到根结点,再根据大小关系划分左右子树,递归判断左右子树是否满足二叉搜索树+后序遍历的两个特点即可。
思路2 非递归
抽象的变换一下形式。把二叉搜索树的左子树,当成其右子树最左边结点的左子树,把每次遍历确定的“根结点”独立出来为一个结点。那么就很容易来通过循环判断了。
这个后序遍历序列,最后一个数(即根结点的值)一定比最开始左子树的大,比最开始右子树的小,那么每次遍历的时候通过二叉搜索树和后序遍历序列的特点来对一个下标变量index进行累加,外层循环每次都对index和序列总长度进行比较:

  • 当index和总长度不想等时,证明这个序列不是合法的后续遍历序列;
  • 当index和总长度不想等时,证明这个序列是合法的后续遍历序列,此时把序列长度减去1,即每次把根节点去掉,再进行循环判断,根基上面提到的两个特点我们可以确定,这样的循环是合理的。

白话一点描述上面的非递归思路

  • 左子树结点值一定比右子树结点值小,因此去掉根结点后,数字分为left,right两部分;
  • right部分的最后一个数字是右子树的根结点,他也比左子树所有值大,因此每次只看右子树是否符合后序遍历的条件即可;
  • 即使到达了左子树,左子树也可以看成是由左、右子树组成的树,依然像右子树那样处理;
  • 对于左子树的处理就像回到了原问题;
  • 对于右子树,左子树的所有值都比右子树的根结点值小,可以暂时把他看成右子树的左子树,只需判断右子树的右子树是否符合要求即可。

代码(Java实现)

思路1 递归代码

/**
 *	@author : flower48237
 *	@version: 2020年3月3日 下午3:28:17 
 */
public class Solution {
	public boolean VerifySquenceOfBST(int []sequence) {
		int size = sequence.length;
        if(0==size)return false;
        while(--size != 0)
        {
        	int i = 0;
            while(sequence[i++]<sequence[size]);
            while(i < size && sequence[i++]>sequence[size]);
 			// 第二个while循环的i < size 是为了防止数组下标越界
            if(i<size)
            	return false;
        }
        return true;
	}
}

思路2 非递归代码

package kd33.VerifySquenceOfBST;
/**
 *	@author : flower48237
 *	@version: 2020年3月3日 下午4:57:02 
 */
public class Solution2 {
	public boolean leaper(int [] sequence, int start, int end) {
		// leaper是递归函数
		if (end <= start) 
        	return true;
        int root = sequence[end];
        
        int i = start;
        for (; i < end; i++) {
        	if (sequence[i] > root) {
        		break;
        	}
        }
        
        int j = i;
        for (; j < end; j++) {
        	if (sequence[j] < root) {
        		return false;
        	}
        }
        return leaper(sequence, start, i - 1) &&leaper(sequence, i, end - 1);
	}
	
	public boolean VerifySquenceOfBST(int []sequence) {
		int size = sequence.length;
		if(size == 0)
        	return false;
		return leaper(sequence, 0, size - 1);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章