算法与数据结构面试题(8)-判断整数序列是不是二元查找树的后序遍历结果

题目


(微软数据结构和算法面试100题中的第9题)

判断整数序列是不是二元查找树的后序遍历结果题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。如果是返回true,否则返回false。例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:


因此返回true。

如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。


解题思路


1.二叉树特点是左子树中所有的节点=<根节点=<右子树中所有的节点

2.后序遍历是先左子树,然后右子树,最后是根节点。所以最后一个数是根节点

3.通过上面的2个特性可以将整个输入分拆若干个子集来求解。用根节点来判断属于左节点还是右节点。


代码


public class Problem9 {

	private boolean isSearchTree(int[] data) {
		if (data == null) {
			System.out.println("数组为空");
			return false;
		}
		if (data.length == 0) {
			System.out.println("为空二叉查找树");
			return true;
		}

		int length = data.length;
		// 根节点
		int rootNode = data[length - 1];
		// 分界索引值
		int separateIndex = getSeparateIndex(data, length, rootNode);
		if (separateIndex == -1) {
			System.out.println("只有左子树");
			// 通过getSeparateIndex可以得知已经遍历的数的大小,如果separateIndex=-1,说明遍历了所有的数都小于根节点
			// 所以也就无需再判断是否有小于根节点的数。
			int[] leftTree = new int[length - 1];
			for (int i = 0; i < length - 1; i++) {
				leftTree[i] = data[i];
			}
			return isSearchTree(leftTree);
		} else if (separateIndex == 0) {
			System.out.println("只有右子树");
			int[] rightTree = new int[length - 1];
			for (int i = 0; i < length - 1;i++) {
				if (data[i] < rootNode) {
					System.out.println("右子树中存在小于根节点的节点: " + data[i]);
					System.out.println("该树不符合二叉查找树的特点");
					return false;
				}
				rightTree[i] = data[i];
			}
			return isSearchTree(rightTree);
		} else {
			System.out.println("该数存在左右子树");
			int[] leftTree = new int[separateIndex];
			int[] rightTree = new int[length - 1 - separateIndex];
			for (int i = 0; i < length-1; i++) {
				if (i < separateIndex) {
					leftTree[i] = data[i];

					// 左子树
				} else {
					// 右子树
					if (data[i] < rootNode) {
						System.out.println("右子树中存在小于根节点的节点: " + data[i]);
						System.out.println("该树不符合二叉查找树的特点");
						return false;
					}
					rightTree[i - separateIndex] = data[i];
				}
			}
			// 先判断左子树是否是符合要求,如果不符合直接返回false。如果如何在判断右子树
			if (!isSearchTree(leftTree))
				return false;
			return isSearchTree(rightTree);

		}
	}

	private int getSeparateIndex(int[] data, int length, int rootNode) {
		// 二叉树特点是左子树中所有的节点=<根节点=<右子树中所有的节点.所以利用根节点来分离左右子树
		int separateIndex = -1;
		for (int i = 0; i < length - 1; i++) {
			if (data[i] > rootNode) {
				separateIndex = i;
				break;
			}
		}
		return separateIndex;
	}

	public static void main(String[] args) {
		int[] data1 = { 5, 7, 6, 9, 11, 10, 8 };
		int[] data2 = { 7, 4, 6, 5 };
		Problem9 problem = new Problem9();
		if (problem.isSearchTree(data1)) {
			System.out.println("data1符合要求");
		} else {
			System.out.println("data1不符合要求");
		}
		System.out.println("===========================");
		if (problem.isSearchTree(data2)) {
			System.out.println("data2符合要求");
		} else {
			System.out.println("data2不符合要求");
		}

	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值