diff --git a/README.adoc b/README.adoc index 17337cbc4d..740a2d600c 100644 --- a/README.adoc +++ b/README.adoc @@ -694,7 +694,7 @@ |{source_base_url}/_0098_ValidateBinarySearchTree.java[Java] |{doc_base_url}/0098-validate-binary-search-tree.adoc[Note] |Medium -| +|树形DP套路或中序遍历 //|99 //|{leetcode_base_url}/recover-binary-search-tree/[Recover Binary Search Tree] diff --git a/docs/0000-21-dynamic-programming.adoc b/docs/0000-21-dynamic-programming.adoc index 787bdf4a80..98da0de015 100644 --- a/docs/0000-21-dynamic-programming.adoc +++ b/docs/0000-21-dynamic-programming.adoc @@ -34,6 +34,10 @@ TIP: 写出信息结构是把所有的信息都装到一个对象中。如果只 + . 第四步:设计递归函数,递归函数是处理以 X 为头节点的情况下的大难,包括设计递归的 base case,默认直接得到左树和右树的所有信息,以及把可能性做整合,并且要返回第三步的信息结构。 +=== 相关试题 + +. xref:0098-validate-binary-search-tree.adoc[98. Validate Binary Search Tree] + == 参考资料 . 左程云《程序员代码面试指南》 diff --git a/docs/0098-validate-binary-search-tree.adoc b/docs/0098-validate-binary-search-tree.adoc index fd408b0bb1..5eaa360b73 100644 --- a/docs/0098-validate-binary-search-tree.adoc +++ b/docs/0098-validate-binary-search-tree.adoc @@ -1,3 +1,4 @@ +[#0098-validate-binary-search-tree] = 98. Validate Binary Search Tree https://leetcode.com/problems/validate-binary-search-tree/[LeetCode - Validate Binary Search Tree] @@ -54,3 +55,26 @@ Assume a BST is defined as follows: include::{sourcedir}/_0098_ValidateBinarySearchTree.java[] ---- + +[{java_src_attr}] +---- +include::{sourcedir}/_0098_ValidateBinarySearchTree_2.java[] +---- + +直接使用“树形DP套路”+剪枝技巧,速度直接击败 100%。 + +这里有一点需要注意:最大值最小值用 `Long.MIN_VALUE` 和 `Long.MAX_VALUE`,这样可以防止单节点树 `Integer.MAX_VALUE` (最小值的单节点树应该也会有问题)造成的错误。 + +另外,查看了官方题解后,发现可以使用树的中序排列来检查(二叉搜索树中序排列是升序),这样跟前几天在牛客网上做的那个“发现二叉搜索树中的两个错误节点”的思路就一致了。回头尝试一下。 + +image::images/0098-01.png[] + +image::images/0098-02.png[] + +image::images/0098-03.png[] + +image::images/0098-04.png[] + +== 参考资料 + +. https://leetcode.cn/problems/validate-binary-search-tree/solutions/230256/yan-zheng-er-cha-sou-suo-shu-by-leetcode-solution/[98. 验证二叉搜索树 - 官方题解^] diff --git a/docs/images/0098-01.png b/docs/images/0098-01.png new file mode 100644 index 0000000000..e21824716e Binary files /dev/null and b/docs/images/0098-01.png differ diff --git a/docs/images/0098-02.png b/docs/images/0098-02.png new file mode 100644 index 0000000000..78b49984a2 Binary files /dev/null and b/docs/images/0098-02.png differ diff --git a/docs/images/0098-03.png b/docs/images/0098-03.png new file mode 100644 index 0000000000..d64c42c8b5 Binary files /dev/null and b/docs/images/0098-03.png differ diff --git a/docs/images/0098-04.png b/docs/images/0098-04.png new file mode 100644 index 0000000000..23189df285 Binary files /dev/null and b/docs/images/0098-04.png differ diff --git a/src/main/java/com/diguage/algorithm/leetcode/_0098_ValidateBinarySearchTree_2.java b/src/main/java/com/diguage/algorithm/leetcode/_0098_ValidateBinarySearchTree_2.java new file mode 100644 index 0000000000..6cf1390ba3 --- /dev/null +++ b/src/main/java/com/diguage/algorithm/leetcode/_0098_ValidateBinarySearchTree_2.java @@ -0,0 +1,64 @@ +package com.diguage.algorithm.leetcode; + +import com.diguage.algorithm.util.TreeNode; + +import java.util.Arrays; + +import static com.diguage.algorithm.util.TreeNodeUtils.buildTree; + +public class _0098_ValidateBinarySearchTree_2 { + public boolean isValidBST(TreeNode root) { + return dfs(root).valid; + } + + private Record dfs(TreeNode node) { + if (node == null) { + return new Record(true, Long.MIN_VALUE, Long.MAX_VALUE); + } + Record left = dfs(node.left); + if (!left.valid) { + return new Record(false, Long.MIN_VALUE, Long.MAX_VALUE); + } + Record right = dfs(node.right); + if (!right.valid) { + return new Record(false, Long.MIN_VALUE, Long.MAX_VALUE); + } + + long max = Math.max(left.max, Math.max(node.val, right.max)); + long min = Math.min(left.min, Math.min(node.val, right.min)); + + return new Record(left.valid && right.valid + && left.max < node.val && node.val < right.min, max, min); + } + + public static class Record { + public boolean valid; + public long max; + public long min; + + public Record(boolean valid, long max, long min) { + this.valid = valid; + this.max = max; + this.min = min; + } + } + + public static void main(String[] args) { + _0098_ValidateBinarySearchTree_2 solution = new _0098_ValidateBinarySearchTree_2(); + + boolean r5 = solution.isValidBST(buildTree(Arrays.asList(2147483647))); + System.out.println(r5); + + boolean r4 = solution.isValidBST(buildTree(Arrays.asList(3, 1, 5, 0, 2, 4, 6, null, null, null, 3))); + System.out.println(r4); + + boolean r3 = solution.isValidBST(buildTree(Arrays.asList(10, 5, 15, null, null, 6, 20))); + System.out.println(r3); + + boolean r1 = solution.isValidBST(buildTree(Arrays.asList(2, 1, 3))); + System.out.println(r1); + + boolean r2 = solution.isValidBST(buildTree(Arrays.asList(5, 1, 4, null, null, 3, 6))); + System.out.println(r2); + } +}