给定一个二叉树,判断其是否是二叉搜索树。
递归。
第一次写的有点问题,有些极端测试用例会无法通过,比如[2147483647]
(单个Integer.MAX_VALUE
)
java
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidNode(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public boolean isValidNode(TreeNode root, int min, int max) {
if(root == null) return true;
if((root.val <= min) || (root.val >= max)) return false;
if(!isValidNode(root.left, min, root.val)) return false;
return isValidNode(root.right, root.val, max);
}
}
主要就是最大值和最小值引发的问题,我们就考虑这两个最值出现的情况好了,最值合法出现的情况至多只会出现一次,而且最大值必定没有右节点,最小值也没有左节点,我们就根据这两条来进行判断
改进版,虽然还有问题:(
java
class Solution {
boolean appearMin = false;
boolean appearMax = false;
public boolean isValidBST(TreeNode root) {
return isValidNode(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public boolean isValidNode(TreeNode root, int min, int max) {
if(root == null) return true;
if((root.val <= min) || (root.val >= max)) {
if(root.val == Integer.MIN_VALUE) {
if(appearMin || root.left != null) {
return false;
}
appearMin = true;
} else if (root.val == Integer.MAX_VALUE) {
if(appearMax || root.right != null) {
return false;
}
appearMax = true;
} else {
return false;
}
}
if(!isValidNode(root.left, min, root.val)) return false;
return isValidNode(root.right, root.val, max);
}
}

调试了一下发现是在Integer.MIN_VALUE
疏忽了和min
的比较,也就是说最值还需要考虑是否在区间内。
java
class Solution {
boolean appearMin = false;
boolean appearMax = false;
public boolean isValidBST(TreeNode root) {
return isValidNode(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public boolean isValidNode(TreeNode root, int min, int max) {
if(root == null) return true;
if((root.val <= min) || (root.val >= max)) {
if(root.val == Integer.MIN_VALUE) {
if(appearMin || root.left != null || root.val < min) {
return false;
}
appearMin = true;
} else if (root.val == Integer.MAX_VALUE) {
if(appearMax || root.right != null || root.val > max) {
return false;
}
appearMax = true;
} else {
return false;
}
}
if(!isValidNode(root.left, min, root.val)) return false;
return isValidNode(root.right, root.val, max);
}
}

Finally succeed!
看了解析是用中序遍历看是否是单调数组这种思路,相对更直观一些,而且不会有最值的问题。
java
class Solution {
public boolean isValidBST(TreeNode root) {
if(root == null) return false;
Stack<TreeNode> st = new Stack<>();
ArrayList<Integer> list = new ArrayList<>();
st.push(root);
while(!st.isEmpty()) {
TreeNode node = st.pop();
if(node == null) {
node = st.pop();
list.add(node.val);
continue;
}
if(node.right != null) {
st.push(node.right);
}
st.push(node);
st.push(null);
if(node.left != null) {
st.push(node.left);
}
}
for (int i = 0; i < list.size() - 1; i++) {
if(list.get(i) >= list.get(i+1)) return false;
}
return true;
}
}

把上述代码优化一下,不额外用数组结构。
java
class Solution {
public boolean isValidBST(TreeNode root) {
if(root == null) return false;
Stack<TreeNode> st = new Stack<>();
st.push(root);
Integer pre = null;
Integer cur = null;
while(!st.isEmpty()) {
TreeNode node = st.pop();
if(node == null) {
node = st.pop();
cur = node.val;
if(pre != null && cur <= pre) return false;
pre = node.val;
continue;
}
if(node.right != null) {
st.push(node.right);
}
st.push(node);
st.push(null);
if(node.left != null) {
st.push(node.left);
}
}
return true;
}
}
还有个有点投机取巧的方法,既然
Integer
的最值不行,就换成Long
的最值
java
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidNode(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean isValidNode(TreeNode root, Long min, Long max) {
if(root == null) return true;
if((root.val <= min) || (root.val >= max)) return false;
if(!isValidNode(root.left, min, (long)root.val)) return false;
return isValidNode(root.right, (long)root.val, max);
}
}
虽然能够通过,但是终究只是回避了最值的问题,如果节点的值能够取到
Long
的最值依然会出现问题。
参考链接:
由于作者水平有限,错误和不当之处在所难免,敬请各位斧正。