剑指offer题解汇总 Java实现
https://blog.csdn.net/guliguliguliguli/article/details/126089434
本题链接
题目
题目主要信息
-
题目给出一个一维数组sequence
-
需要判断该数组sequence中的元素是否符合一个二叉搜索树的后序遍历顺序
-
如果该数组sequence可以是一种二叉搜索树的后序遍历顺序,则返回true
-
如果该数组sequence非二叉搜索树的后序遍历顺序,则返回false
-
方案一 单调栈(还没理解)
栈是一种仅支持在表尾进行插入和删除操作的线性表,这一端被称为栈顶,另一端被称为栈底
-
元素入栈指的是把新元素放到栈顶元素上面,使之成为新的栈顶元素
-
元素出栈指的是从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,是其相邻的元素成为新的栈顶元素
官方给的这个方法还没理解…
方案二 二叉树递归
递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能将原本的问题分解为更小的子问题,这是使用递归的关键。
思路
递归函数的参数包含三个信息:
- 遍历序列
- 树的起点索引位置
- 树的终点索引位置
对于后序遍历的二叉搜索树来讲,终点位置就是根,然后从后往前找到第一个小于终点位置的节点,就是在序列中划分左右子树的分割位置。
只要能一直划分下去,直到递归最后是单个节点,则说明应该返回true
,否则返回false
。
具体做法
-
首先对于给定列表长度为0的特殊情况返回
false
-
递归函数中返回条件为
l>=r
,则返回true
-
递归函数中确定根节点为
sequence[r]
,然后从后往前遍历找到左右子树分割点,进行继续递归
下面代码在官方所给代码上做了一定的修改,两个for循环的起始条件
import java.util.*;
public class Solution {
public boolean VerifySquenceOfBST(int[] sequence) {
if (sequence.length == 0) {
return false;
}
return order(sequence, 0, sequence.length - 1);
}
public boolean order(int[] sequence, int l, int r) {
// 剩一个节点的时候 返回 true
if (l >= r) {
return true;
}
int j;
//mid用来记录根节点
int mid = sequence[r];
// 找到左子树和右子树的分界点,j代表左子树的最后一个索引位置
//通过下面循环,cur最后为根节点,左子树后序遍历的最后一个节点
for (j = r - 1; j >= l; j--) {
int cur = sequence[j];
if (cur < mid) {
break;
}
}
// 判断所谓的左子树中是否又不合法(不符合二叉搜索树)的元素
for (int i = j - 1; i >= l; i--) {
int cur = sequence[i];
if (cur > mid) {
return false;
}
}
return order(sequence, l, j) && order(sequence, j + 1, r - 1);
}
}