9
9
10
10
## 解法
11
11
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$ 是二叉树的节点个数。
13
19
14
20
<!-- tabs:start -->
15
21
16
22
``` python
17
23
# Definition for a binary tree node.
18
24
# 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
25
29
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)
27
41
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)
42
44
```
43
45
44
46
``` java
@@ -48,29 +50,34 @@ class Solution:
48
50
* int val;
49
51
* TreeNode left;
50
52
* 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
+ * }
52
60
* }
53
61
*/
54
62
class Solution {
55
- private boolean res = true ;
56
- private Integer t = null ;
63
+ private TreeNode prev ;
64
+
57
65
public boolean isValidBST (TreeNode root ) {
58
- isValid(root);
59
- return res;
66
+ return dfs(root);
60
67
}
61
68
62
- private void isValid (TreeNode root ) {
69
+ private boolean dfs (TreeNode root ) {
63
70
if (root == null ) {
64
- return ;
71
+ return true ;
65
72
}
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 ;
72
78
}
73
- isValid(root. right);
79
+ prev = root;
80
+ return dfs(root. right);
74
81
}
75
82
}
76
83
```
@@ -82,54 +89,59 @@ class Solution {
82
89
* int val;
83
90
* TreeNode *left;
84
91
* 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) {}
86
95
* };
87
96
*/
88
97
class Solution {
89
98
public:
90
99
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;
106
104
}
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);
109
115
}
110
116
};
111
117
```
112
118
113
119
```go
120
+ /**
121
+ * Definition for a binary tree node.
122
+ * type TreeNode struct {
123
+ * Val int
124
+ * Left *TreeNode
125
+ * Right *TreeNode
126
+ * }
127
+ */
114
128
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
122
134
}
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) {
128
136
return false
129
137
}
130
- node = node.Right
138
+ if prev != nil && prev.Val >= root.Val {
139
+ return false
140
+ }
141
+ prev = root
142
+ return dfs(root.Right)
131
143
}
132
- return true
144
+ return dfs(root)
133
145
}
134
146
```
135
147
@@ -149,17 +161,19 @@ func isValidBST(root *TreeNode) bool {
149
161
*/
150
162
151
163
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 ) {
155
167
return true ;
156
168
}
157
- const { val, left, right } = root ;
158
- if (! dfs (left ) || val <= pre ) {
169
+ if (! dfs (root .left )) {
159
170
return false ;
160
171
}
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 );
163
177
};
164
178
return dfs (root );
165
179
}
@@ -187,19 +201,19 @@ function isValidBST(root: TreeNode | null): boolean {
187
201
use std :: rc :: Rc ;
188
202
use std :: cell :: RefCell ;
189
203
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 {
191
205
if root . is_none () {
192
206
return true ;
193
207
}
194
208
let root = root . as_ref (). unwrap (). borrow ();
195
- if ! Self :: dfs (& root . left, pre ) {
209
+ if ! Self :: dfs (& root . left, prev ) {
196
210
return false ;
197
211
}
198
- if pre . is_some () && pre . unwrap () >= root . val {
212
+ if prev . is_some () && prev . unwrap () >= root . val {
199
213
return false ;
200
214
}
201
- * pre = Some (root . val);
202
- Self :: dfs (& root . right, pre )
215
+ * prev = Some (root . val);
216
+ Self :: dfs (& root . right, prev )
203
217
}
204
218
205
219
pub fn is_valid_bst (root : Option <Rc <RefCell <TreeNode >>>) -> bool {
@@ -208,59 +222,72 @@ impl Solution {
208
222
}
209
223
```
210
224
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
+ };
231
255
```
232
256
233
- ``` ts
257
+ ``` cs
234
258
/**
235
259
* 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;
244
268
* }
245
269
* }
246
270
*/
271
+ public class Solution {
272
+ private TreeNode prev ;
247
273
248
- function isValidBST(root : TreeNode | null ): boolean {
249
- if (root == null ) {
250
- return true ;
274
+ public bool IsValidBST (TreeNode root ) {
275
+ return dfs (root );
251
276
}
252
- const { val, left, right } = root ;
253
- const dfs = ( root : TreeNode | null , min : number , max : number ) => {
277
+
278
+ private bool dfs ( TreeNode root ) {
254
279
if (root == null ) {
255
280
return true ;
256
281
}
257
- const { val, left, right } = root ;
258
- if (val <= min || val >= max ) {
282
+ if (! dfs (root .left )) {
259
283
return false ;
260
284
}
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
+ }
264
291
}
265
292
```
266
293
0 commit comments