剣はオファー33を指します。二分探索木のポストオーダートラバーサルシーケンス
タイトル説明
問題解決のアイデア
通常の二分木のポストオーダートラバーサルシーケンスのみがわかっている場合、左右の二分木の添え字範囲を決定できないため、元の二分木を復元することはできません。
しかし、この質問は二分探索木であり、特別なプロパティに基づいて左右のサブツリーの添え字範囲を決定できます。
また、場合endOfLeft
とindex
下降するとき、私たちは、に注意を払うに必要な添字クロスボーダーの問題、ここで左マージンは0ではありませんが、始めます。
class Solution {
public boolean verifyPostorder(int[] postorder) {
if (postorder.length == 0) return true;
return verifyPostorder(postorder, 0, postorder.length - 1);
}
//判断 postorder[begin...end] 是否是二叉搜索树的后序遍历结果
public boolean verifyPostorder(int[] postorder, int begin, int end) {
// base case
if (begin >= end) return true;
int endOfLeft = end; //左子树的结束索引
//左子树结束索引对应的元素是第一个比 postorder[end] 小的元素
while (endOfLeft >= begin && postorder[endOfLeft] >= postorder[end]) endOfLeft--;
//由于上面 while 遍历时,已经确保了右子树的所有元素都大于 postorder[end],所以要继续判断左子树的正确性
int index = endOfLeft;
while (index >= begin && postorder[index] < postorder[end]) index--;
//首先要保证左子树的正确性,然后继续遍历左子树和右子树
return (index + 1 == begin) && verifyPostorder(postorder, begin, endOfLeft)
&& verifyPostorder(postorder, endOfLeft + 1, end - 1);
}
}