Skip to content

Commit f377b03

Browse files
authored
feat: add solutions to lc/lcci problems (#2647)
* lc No.0098.Validate Binary Search Tree * lcci No.04.05.Legal Binary Search Tree
1 parent 9358251 commit f377b03

25 files changed

+665
-902
lines changed

lcci/04.05.Legal Binary Search Tree/README.md

+146-119
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,38 @@
99

1010
## 解法
1111

12-
### 方法一
12+
### 方法一:递归
13+
14+
我们可以对二叉树进行递归中序遍历,如果遍历到的结果是严格升序的,那么这棵树就是一个二叉搜索树。
15+
16+
因此,我们使用一个变量 $\textit{prev}$ 来保存上一个遍历到的节点,初始时 $\textit{prev} = -\infty$,然后我们递归遍历左子树,如果左子树不是二叉搜索树,直接返回 $\text{False}$,否则判断当前节点的值是否大于 $\textit{prev}$,如果不是,返回 $\text{False}$,否则更新 $\textit{prev}$ 为当前节点的值,然后递归遍历右子树。
17+
18+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点个数。
1319

1420
<!-- tabs:start -->
1521

1622
```python
1723
# Definition for a binary tree node.
1824
# class TreeNode:
19-
# def __init__(self, x):
20-
# self.val = x
21-
# self.left = None
22-
# self.right = None
23-
24-
25+
# def __init__(self, val=0, left=None, right=None):
26+
# self.val = val
27+
# self.left = left
28+
# self.right = right
2529
class Solution:
26-
res, t = True, None
30+
def isValidBST(self, root: Optional[TreeNode]) -> bool:
31+
def dfs(root: Optional[TreeNode]) -> bool:
32+
if root is None:
33+
return True
34+
if not dfs(root.left):
35+
return False
36+
nonlocal prev
37+
if prev >= root.val:
38+
return False
39+
prev = root.val
40+
return dfs(root.right)
2741

28-
def isValidBST(self, root: TreeNode) -> bool:
29-
self.isValid(root)
30-
return self.res
31-
32-
def isValid(self, root):
33-
if not root:
34-
return
35-
self.isValid(root.left)
36-
if self.t is None or self.t < root.val:
37-
self.t = root.val
38-
else:
39-
self.res = False
40-
return
41-
self.isValid(root.right)
42+
prev = -inf
43+
return dfs(root)
4244
```
4345

4446
```java
@@ -48,29 +50,34 @@ class Solution:
4850
* int val;
4951
* TreeNode left;
5052
* TreeNode right;
51-
* TreeNode(int x) { val = x; }
53+
* TreeNode() {}
54+
* TreeNode(int val) { this.val = val; }
55+
* TreeNode(int val, TreeNode left, TreeNode right) {
56+
* this.val = val;
57+
* this.left = left;
58+
* this.right = right;
59+
* }
5260
* }
5361
*/
5462
class Solution {
55-
private boolean res = true;
56-
private Integer t = null;
63+
private TreeNode prev;
64+
5765
public boolean isValidBST(TreeNode root) {
58-
isValid(root);
59-
return res;
66+
return dfs(root);
6067
}
6168

62-
private void isValid(TreeNode root) {
69+
private boolean dfs(TreeNode root) {
6370
if (root == null) {
64-
return;
71+
return true;
6572
}
66-
isValid(root.left);
67-
if (t == null || t < root.val) {
68-
t = root.val;
69-
} else {
70-
res = false;
71-
return;
73+
if (!dfs(root.left)) {
74+
return false;
75+
}
76+
if (prev != null && prev.val >= root.val) {
77+
return false;
7278
}
73-
isValid(root.right);
79+
prev = root;
80+
return dfs(root.right);
7481
}
7582
}
7683
```
@@ -82,54 +89,59 @@ class Solution {
8289
* int val;
8390
* TreeNode *left;
8491
* TreeNode *right;
85-
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
92+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
93+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
94+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
8695
* };
8796
*/
8897
class Solution {
8998
public:
9099
bool isValidBST(TreeNode* root) {
91-
TreeNode* pre = nullptr;
92-
TreeNode* cur = root;
93-
stack<TreeNode*> stk;
94-
while (cur || !stk.empty()) {
95-
if (cur) {
96-
stk.push(cur);
97-
cur = cur->left;
98-
} else {
99-
cur = stk.top();
100-
stk.pop();
101-
if (pre && pre->val >= cur->val) {
102-
return false;
103-
}
104-
pre = cur;
105-
cur = cur->right;
100+
TreeNode* prev = nullptr;
101+
function<bool(TreeNode*)> dfs = [&](TreeNode* root) {
102+
if (!root) {
103+
return true;
106104
}
107-
}
108-
return true;
105+
if (!dfs(root->left)) {
106+
return false;
107+
}
108+
if (prev && prev->val >= root->val) {
109+
return false;
110+
}
111+
prev = root;
112+
return dfs(root->right);
113+
};
114+
return dfs(root);
109115
}
110116
};
111117
```
112118
113119
```go
120+
/**
121+
* Definition for a binary tree node.
122+
* type TreeNode struct {
123+
* Val int
124+
* Left *TreeNode
125+
* Right *TreeNode
126+
* }
127+
*/
114128
func isValidBST(root *TreeNode) bool {
115-
stack := make([]*TreeNode, 0)
116-
var prev *TreeNode = nil
117-
node := root
118-
for len(stack) > 0 || node != nil {
119-
for node != nil {
120-
stack = append(stack, node)
121-
node = node.Left
129+
var prev *TreeNode
130+
var dfs func(*TreeNode) bool
131+
dfs = func(root *TreeNode) bool {
132+
if root == nil {
133+
return true
122134
}
123-
node = stack[len(stack)-1]
124-
stack = stack[:len(stack)-1]
125-
if prev == nil || node.Val > prev.Val {
126-
prev = node
127-
} else {
135+
if !dfs(root.Left) {
128136
return false
129137
}
130-
node = node.Right
138+
if prev != nil && prev.Val >= root.Val {
139+
return false
140+
}
141+
prev = root
142+
return dfs(root.Right)
131143
}
132-
return true
144+
return dfs(root)
133145
}
134146
```
135147

@@ -149,17 +161,19 @@ func isValidBST(root *TreeNode) bool {
149161
*/
150162

151163
function isValidBST(root: TreeNode | null): boolean {
152-
let pre = -Infinity;
153-
const dfs = (root: TreeNode | null) => {
154-
if (root == null) {
164+
let prev: TreeNode | null = null;
165+
const dfs = (root: TreeNode | null): boolean => {
166+
if (!root) {
155167
return true;
156168
}
157-
const { val, left, right } = root;
158-
if (!dfs(left) || val <= pre) {
169+
if (!dfs(root.left)) {
159170
return false;
160171
}
161-
pre = val;
162-
return dfs(right);
172+
if (prev && prev.val >= root.val) {
173+
return false;
174+
}
175+
prev = root;
176+
return dfs(root.right);
163177
};
164178
return dfs(root);
165179
}
@@ -187,19 +201,19 @@ function isValidBST(root: TreeNode | null): boolean {
187201
use std::rc::Rc;
188202
use std::cell::RefCell;
189203
impl Solution {
190-
fn dfs(root: &Option<Rc<RefCell<TreeNode>>>, pre: &mut Option<i32>) -> bool {
204+
fn dfs(root: &Option<Rc<RefCell<TreeNode>>>, prev: &mut Option<i32>) -> bool {
191205
if root.is_none() {
192206
return true;
193207
}
194208
let root = root.as_ref().unwrap().borrow();
195-
if !Self::dfs(&root.left, pre) {
209+
if !Self::dfs(&root.left, prev) {
196210
return false;
197211
}
198-
if pre.is_some() && pre.unwrap() >= root.val {
212+
if prev.is_some() && prev.unwrap() >= root.val {
199213
return false;
200214
}
201-
*pre = Some(root.val);
202-
Self::dfs(&root.right, pre)
215+
*prev = Some(root.val);
216+
Self::dfs(&root.right, prev)
203217
}
204218

205219
pub fn is_valid_bst(root: Option<Rc<RefCell<TreeNode>>>) -> bool {
@@ -208,59 +222,72 @@ impl Solution {
208222
}
209223
```
210224

211-
<!-- tabs:end -->
212-
213-
### 方法二
214-
215-
<!-- tabs:start -->
216-
217-
```go
218-
func isValidBST(root *TreeNode) bool {
219-
return check(root, math.MinInt64, math.MaxInt64)
220-
}
221-
222-
func check(node *TreeNode, lower, upper int) bool {
223-
if node == nil {
224-
return true
225-
}
226-
if node.Val <= lower || node.Val >= upper {
227-
return false
228-
}
229-
return check(node.Left, lower, node.Val) && check(node.Right, node.Val, upper)
230-
}
225+
```js
226+
/**
227+
* Definition for a binary tree node.
228+
* function TreeNode(val, left, right) {
229+
* this.val = (val===undefined ? 0 : val)
230+
* this.left = (left===undefined ? null : left)
231+
* this.right = (right===undefined ? null : right)
232+
* }
233+
*/
234+
/**
235+
* @param {TreeNode} root
236+
* @return {boolean}
237+
*/
238+
var isValidBST = function (root) {
239+
let prev = null;
240+
const dfs = root => {
241+
if (!root) {
242+
return true;
243+
}
244+
if (!dfs(root.left)) {
245+
return false;
246+
}
247+
if (prev && prev.val >= root.val) {
248+
return false;
249+
}
250+
prev = root;
251+
return dfs(root.right);
252+
};
253+
return dfs(root);
254+
};
231255
```
232256

233-
```ts
257+
```cs
234258
/**
235259
* Definition for a binary tree node.
236-
* class TreeNode {
237-
* val: number
238-
* left: TreeNode | null
239-
* right: TreeNode | null
240-
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
241-
* this.val = (val===undefined ? 0 : val)
242-
* this.left = (left===undefined ? null : left)
243-
* this.right = (right===undefined ? null : right)
260+
* public class TreeNode {
261+
* public int val;
262+
* public TreeNode left;
263+
* public TreeNode right;
264+
* public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
265+
* this.val = val;
266+
* this.left = left;
267+
* this.right = right;
244268
* }
245269
* }
246270
*/
271+
public class Solution {
272+
private TreeNode prev;
247273

248-
function isValidBST(root: TreeNode | null): boolean {
249-
if (root == null) {
250-
return true;
274+
public bool IsValidBST(TreeNode root) {
275+
return dfs(root);
251276
}
252-
const { val, left, right } = root;
253-
const dfs = (root: TreeNode | null, min: number, max: number) => {
277+
278+
private bool dfs(TreeNode root) {
254279
if (root == null) {
255280
return true;
256281
}
257-
const { val, left, right } = root;
258-
if (val <= min || val >= max) {
282+
if (!dfs(root.left)) {
259283
return false;
260284
}
261-
return dfs(left, min, Math.min(val, max)) && dfs(right, Math.max(val, min), max);
262-
};
263-
return dfs(left, -Infinity, val) && dfs(right, val, Infinity);
285+
if (prev != null && prev.val >= root.val) {
286+
return false;
287+
}
288+
prev = root;
289+
return dfs(root.right);
290+
}
264291
}
265292
```
266293

0 commit comments

Comments
 (0)