-
Notifications
You must be signed in to change notification settings - Fork 43
/
ValidateBinarySearchTree.java
155 lines (128 loc) · 4.59 KB
/
ValidateBinarySearchTree.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package LeetCodeJava.Recursion;
// https://leetcode.com/problems/validate-binary-search-tree/
import LeetCodeJava.DataStructure.TreeNode;
import java.util.Deque;
import java.util.LinkedList;
/**
* A valid BST is defined as follows:
*
* 1) The left subtree of a node contains only nodes with keys less than the node's key.
* 2) The right subtree of a node contains only nodes with keys greater than the node's key.
* 3) Both the left and right subtrees must also be binary search trees.
*/
public class ValidateBinarySearchTree {
// V0
// IDEA : DFS + BST property + setup smallest, biggest val
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
/** NOTE !!!
*
* since for valid BST, all its sub-tree needs to be valid BST as well,
* so we need to keep comparing sub-tree with "its root and its sub-tree"
* -> so we need to set up a "tree-wide" smallest, and biggest value,
* -> for "left sub tree val < root.val < right sub tree val" check
*
* if any sub-tree failed to meet BST requirement
* (e.g. left sub tree val < root.val < right sub tree val),
* then this tree is NOT a BST
*/
/**
* NOTE !!!
*
* Use long to handle edge cases for Integer.MIN_VALUE and Integer.MAX_VALUE
* -> use long to handle overflow issue (NOT use int type)
*/
long smallest_val = Long.MIN_VALUE;
long biggest_val = Long.MAX_VALUE;
return check_(root, smallest_val, biggest_val);
}
public boolean check_(TreeNode root, long smallest_val, long biggest_val) {
if (root == null) {
return true;
}
// if (root.val <= smallest_val || root.val >= biggest_val) {
// return false;
// }
if (root.val <= smallest_val){
return false;
}
if (root.val >= biggest_val){
return false;
}
return check_(root.left, smallest_val, root.val) &&
check_(root.right, root.val, biggest_val);
}
// V1
// IDEA : Recursive Traversal with Valid Range
// https://leetcode.com/problems/validate-binary-search-tree/editorial/
public boolean validate(TreeNode root, Integer low, Integer high) {
// Empty trees are valid BSTs.
if (root == null) {
return true;
}
// The current node's value must be between low and high.
if ((low != null && root.val <= low) || (high != null && root.val >= high)) {
return false;
}
// The left and right subtree must also be valid.
return validate(root.right, root.val, high) && validate(root.left, low, root.val);
}
public boolean isValidBST_2(TreeNode root) {
return validate(root, null, null);
}
// V2
// IDEA : Iterative Traversal with Valid Range
// https://leetcode.com/problems/validate-binary-search-tree/editorial/
private Deque<TreeNode> stack = new LinkedList();
private Deque<Integer> upperLimits = new LinkedList();
private Deque<Integer> lowerLimits = new LinkedList();
public void update(TreeNode root, Integer low, Integer high) {
stack.add(root);
lowerLimits.add(low);
upperLimits.add(high);
}
public boolean isValidBST_3(TreeNode root) {
Integer low = null, high = null, val;
update(root, low, high);
while (!stack.isEmpty()) {
root = stack.poll();
low = lowerLimits.poll();
high = upperLimits.poll();
if (root == null) continue;
val = root.val;
if (low != null && val <= low) {
return false;
}
if (high != null && val >= high) {
return false;
}
update(root.right, val, high);
update(root.left, low, val);
}
return true;
}
// V3
// IDEA : Recursive Inorder Traversal
// https://leetcode.com/problems/validate-binary-search-tree/editorial/
// We use Integer instead of int as it supports a null value.
private Integer prev;
public boolean isValidBST_4(TreeNode root) {
prev = null;
return inorder(root);
}
private boolean inorder(TreeNode root) {
if (root == null) {
return true;
}
if (!inorder(root.left)) {
return false;
}
if (prev != null && root.val <= prev) {
return false;
}
prev = root.val;
return inorder(root.right);
}
}