剑指 Offer(第2版)面试题 33:二叉搜索树的后序遍历序列

剑指 Offer(第2版)面试题 33:二叉搜索树的后序遍历序列

  • 剑指 Offer(第2版)面试题 33:二叉搜索树的后序遍历序列
    • 解法1:递归

剑指 Offer(第2版)面试题 33:二叉搜索树的后序遍历序列

题目来源:46. 二叉搜索树的后序遍历序列

解法1:递归

什么是二叉搜索树(BST)?

它或者是一棵空树,或者是具有下列性质的二叉树:

  1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。

后序遍历序列的最后一个值是二叉树的根节点。

二叉搜索树的后序遍历序列的前面的值一部分小于根节点,一部分大于根节点。

算法:

  1. 对于范围为 [begin, end] 的一段序列 sequence,将 sequence[end] 作为根节点的值,记为 rootValue。
  2. 初始化 splitIndex = begin,向后遍历 sequence,直到找到第一个满足 sequence[splitIndex] > rootValue 的 plitIndex。
  3. 由此得到根节点的两棵子树的区间:左子树区间为 [begin, splitIndex - 1],右子树区间为 [splitIndex, end - 1]。
  4. 遍历右子树区间 [splitIndex, end - 1],若发现该区间有值小于 rootValue,则不满足 BST 的特性,返回 false。
  5. 递归下去判断左子树区间和右子树区间是否是后序遍历序列。

代码:

class Solution
{
public:
	bool verifySequenceOfBST(vector<int> sequence)
	{
		// 特判
		if (sequence.size() <= 1)
			return true;
		return postOfBST(sequence, 0, sequence.size() - 1);
	}
	// 辅函数 - 递归判断
	bool postOfBST(vector<int> &sequence, int begin, int end)
	{
		if (begin >= end)
			return true;
		int splitIndex = begin, rootValue = sequence[end];
		while (splitIndex < end && sequence[splitIndex] <= rootValue)
			splitIndex++;
		for (int i = splitIndex; i < end; i++)
			if (sequence[i] < rootValue)
				return false;
		return postOfBST(sequence, begin, splitIndex - 1) && postOfBST(sequence, splitIndex, end - 1);
	}
};

复杂度分析:

时间复杂度:O(n),其中 n 是二叉树的节点个数。

空间复杂度:O(depth),其中 depth 是二叉树的深度。

你可能感兴趣的:(剑指,Offer,剑指Offer,C++,二叉树,递归)