1 题目
2 Java
2.1 方法一(递归)
核心是,一段后序遍历数组,分左右根三部分,最后一个元素是根节点,前面分为两部分(左子树和右子树),前一部分都比根节点小,中间一部分都比根节点大
递归思路:针对一段数组,从左开始遍历,先都比最后一个元素小,接着都比最后一个元素大,然后停止,若无法遍历到最后一个元素,说明该段数组不可能是任何二叉搜索树的后序遍历
class Solution {
public boolean verifyPostorder(int[] postorder) {
if(postorder.length <= 2) return true;
return helper(postorder, 0, postorder.length - 1);
}
public boolean helper(int[] postorder, int l, int r){
if(l >= r) return true;
int rootVal = postorder[r];
int i = l;
while(postorder[i] < rootVal && i < r) i++;
int mid = i;
while(rootVal < postorder[i] && i < r) i++;
if(i < r) return false;
return helper(postorder, l, mid - 1) && helper(postorder, mid, r - 1);
}
}
写成快排、归并那种分治的形式
class Solution {
public boolean verifyPostorder(int[] postorder) {
function(postorder, 0, postorder.length - 1);
return res;
}
boolean res = true;
public void function(int[] postorder, int l, int r){
if(l >= r) return;
int m = helper(postorder, l, r);
if(m == -1){
res = false;
return;
}
function(postorder, l, m - 1);
function(postorder, m, r - 1); // 神坑!!!是 r-1
}
public int helper(int[]arrs, int l, int r){
int sentry = arrs[r];
int i = l;
while(arrs[i] < sentry) i++;
int m = i; // 神坑!!!返回的必须是i(右子树第一个元素),而不能是i-1(左子树最后一个元素)
while(arrs[i] > sentry) i++;
if(i != r) return -1;
return m;
}
}