1. 程式人生 > >劍指offer面試題24 二叉搜尋樹的後序遍歷序列

劍指offer面試題24 二叉搜尋樹的後序遍歷序列

解題思路:
1.判定一個序列是不是某二叉搜尋樹的後續遍歷序列,可以結合二叉樹的後續序列和二叉搜尋樹的特點來判斷。二叉樹的後續遍歷序列,其最後一個數字是樹的根節點的值,根節點的前面部分可以分為左子樹的序列和右子樹的序列。而這顆二叉樹需要是一顆二叉搜尋樹,又必須滿足左子樹上的所有節點小於根節點的值,右子樹上的所有節點大於根節點的值。接下來,針對左子樹和右子樹,分別需要滿足上述條件,顯然這是一個遞迴的過程。

2.具體來說:針對某一棵樹,根據後續序列容易確定根節點的值,接下來需要確定左子樹和右子樹的範圍。在當前序列中找出左子樹與右子樹的分界線,然後在子樹上重複上述步驟。

public class Solution {
	
	public static boolean VerifySquenceOfBST(int[] sequence) {
		
		if (sequence == null || sequence.length == 0) {
			return false;
		}
		
		int start = 0; 
		int end = sequence.length - 1;
		
		boolean result = VerifySquenceOfBST_Recursive(sequence, start, end);
		return result;
	}

	private static boolean VerifySquenceOfBST_Recursive(int[] sequence, int start, int end) {
		
		if (start == end) {
			return true;
		}
		
		if (start > end) {
			return false;
		}
		//取到當前樹的根
		int root = sequence[end];
		//在當前陣列範圍中找到左子樹和右子樹的分界線
		int border = start;
		while (sequence[border] < root) {
			border++;
		}
		
		//此時border指向右子樹的開始位置,並且保證border的左邊都是比根小的元素
		//還必須保證右子樹中所有元素都是比根大的元素
		for (int i = border; i < end; i++) {
			if (sequence[i] < root) {
				//如果在右子樹中存在比根元素小的,則該序列肯定不是二叉搜尋樹的後序序列
				return false;
			}
		}
		
		//如果只存在左子樹
		if (border == end) {
			return VerifySquenceOfBST_Recursive(sequence, start, border - 1);
		}
		
		//如果只存在右子樹
		if(border == start) {
			return VerifySquenceOfBST_Recursive(sequence, border, end - 1);
		}
		
		boolean left = VerifySquenceOfBST_Recursive(sequence, start, border - 1);
		boolean right = VerifySquenceOfBST_Recursive(sequence, border, end - 1);
		return left && right;
	}
	
}