1 题目
https://leetcode.cn/problems/validate-binary-search-tree/description/
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含
小于
当前节点的数。 - 节点的右子树只包含
大于
当前节点的数。 - 所有左子树和右子树自身必须也是二叉搜索树。
2 思路
根据上面的规则,递归判断
当出现不满足条件的节点,则返回false
当遍历所有的节点后,没有出现false的情况,则为true
注意:递归时的返回值
class Solution{
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
boolean result = true;
if (root.left != null) result = root.left.val < root.val;
if (root.right != null) result = root.val < root.right.val;
if (!result) return result;
result = isValidBST(root.left);
if (!result) return result;
result = isValidBST(root.right);
if (!result) return result;
return true;
}
}
ACM输入输出
import java.util.*;
class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode() {}
public TreeNode(int val) {this.val = val; }
}
// solution
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Solution solution = new Solution();
while (in.hasNext()) {
String[] strNums = in.nextLine().split(" ");
List<TreeNode> nodes = new LinkedList<>();
for (String strNum: strNums) {
if (!strNum.isEmpty()) {
if (strNum.equals("null")) {
nodes.add(null);
} else {
nodes.add(new TreeNode(Integer.parseInt(strNum)));
}
}
}
TreeNode root = constructTree(nodes);
boolean r = solution.isValidBST(root);
System.out.println(r);
}
}
public static TreeNode constructTree(List<TreeNode> nodes) {
if (!nodes.isEmpty()) {
TreeNode node = nodes.remove(0);
if (node != null) {
node.left = constructTree(nodes);
node.right = constructTree(nodes);
}
return node;
}
return null;
}
}
BUG1
逐个比较的问题,不能比较整个子树;当右子树中出现不合法的情况查不出来
10 5 null null 15 6 null null 20
正确答案: false
程序结果: true
FIX1 中序递归
二叉搜索树的先验知识:中序遍历二叉搜索树,这个序列为递增序列
知道这点后,可以获取中序遍历的序列,检测其是否递增即可
对于上面的代码如何改进?
采用中序遍历的方式,检测元素是否递增
class Solution {
private long maxVal = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
boolean left = isValidBST(root.left);
if (!left) return false;
// 检测中序元素是否递增
if (maxVal < root.val) maxVal = root.val;
else return false;
boolean right = isValidBST(root.right);
if (!right) return false;
return true;
}
}
小问题:
样例中最小节点可能是int的最小值,会比较出错;此时可以初始化比较元素为long
的最小值。
FIX2 遍历
获取序列,检测是否递增
class Solution {
public boolean isValidBST(TreeNode root) {
List<Integer> numList = new LinkedList<>();
inorderBST(root, numList);
for (int i = 0; i < numList.size() - 1; i++) {
if (numList.get(i) >= numList.get(i+1)) return false;
}
return true;
}
private void inorderBST(TreeNode root, List<Integer> numList) {
if (root != null) {
inorderBST(root.left, numList);
numList.add(root.val);
inorderBST(root.right, numList);
}
}
}
遍历的方式最慢,因为要彻底遍历整个树;对于递归的情况,如果遇到不满足的情况就即刻返回了,不会遍历整个树;