我先吐槽一下,我只能说这个题的测试用例有一点恶心,疯狂安排边界条件,就是Integer的最小值和最大值。主要自己考虑的不周到吧,就因为这个提交好几次都是错的…不过思路上还是对的。
既然是一个二叉排序树,那么符合它的定义:根的左边始终小于根节点,根的右边始终大于根节点。所以就想到了使用中序遍历,中序遍历是先遍历左子树,再遍历根节点,再遍历右子树,那么两者顺序是一致的,所以只要在中序遍历中始终记住上一个元素,和现在的元素做对比,如果小于现在的元素,则继续遍历,否则返回false。
当然这个地方用的是中序遍历的非递归实现,因为递归实现貌似还要记住元素,传进函数参数…其实我也没有仔细想,只是觉得非递归实现起来也不难,而且每次只需要比较并更改上一个遍历过的元素pre即可。那就直接上代码:
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack();
double inorder = - Double.MAX_VALUE;
while (!stack.isEmpty() || root != null) {
while (root != null) { //将所有的左节点依次进栈
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.val <= inorder) return false;
inorder = root.val;
root = root.right; //看弹出节点的右子树,如果有将右子树的所有左节点进栈,为下次循环做准备
}
return true;
}
当然,这个问题还有一种解法就是递归判断。刚开始我的思路是想递归判断某一个子树是不是,但是发现那样根本不行,即使是某一个子树符合,但是整体仍然会不符合。其实我忽略了一个条件,也就是虽然是子树符合,但是我么假设了子树中要比较的值就是这个子树的根节点,但其实我们不能和它比较,要在全局上进行考虑。细节可以看一下这个题目的solution.