40
40
41
41
## 解法
42
42
43
- 朴素解法:
43
+ ** 方法一:反序中序遍历 **
44
44
45
- 1 . 中序遍历,并使用数组存储遍历结果。
46
- 2 . 遍历结束,返回 ` arr[arr.length - k] ` 。
45
+ 由于二叉搜索树的中序遍历是升序的,因此可以反序中序遍历,即先递归遍历右子树,再访问根节点,最后递归遍历左子树。
47
46
48
- _ 优化 _ :
47
+ 这样就可以得到一个降序的序列,第 $k$ 个节点就是第 $k$ 大的节点。
49
48
50
- 其中,只关注** 第 k 大节点的值** ,可以选择倒序遍历,记录当前遍历节点的数量,当数量为 ` k ` 时,记录当前节点值做为返回值即可,而无需记录所有的遍历结果。
51
-
52
- > 中序遍历的顺序是从小到大,倒序的中序遍历便是从大到小。
53
-
54
- 常规中序遍历:
55
-
56
- ``` txt
57
- IN-ORDER(R)
58
- IN-ORDER(R.left)
59
- print(R.val)
60
- In-ORDER(R.right)
61
- ```
62
-
63
- 倒序中序遍历:
64
-
65
- ``` txt
66
- IN-ORDER-REVERSE(R)
67
- In-ORDER-REVERSE(R.right)
68
- print(R.val)
69
- IN-ORDER-REVERSE(R.left)
70
- ```
71
-
72
- 若是抬杠说,可能每次 ` k ` 都是节点数量,那么倒序就毫无意义并且加长时间消耗。这些情况是无法假设的,如果 ` k = 1 ` ,那又该怎么说,选择倒序先得最大值,才是符合题意的精神。
49
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉搜索树的节点个数。
73
50
74
51
<!-- tabs:start -->
75
52
@@ -86,19 +63,19 @@ IN-ORDER-REVERSE(R)
86
63
87
64
class Solution :
88
65
def kthLargest (self , root : TreeNode, k : int ) -> int :
89
- def inorder (root ):
90
- if root is None :
91
- return
92
- inorder(root.right)
93
- self .cur -= 1
94
- if self .cur == 0 :
95
- self .res = root.val
66
+ def dfs (root ):
67
+ nonlocal k, ans
68
+ if root is None or k == 0 :
96
69
return
97
- inorder(root.left)
98
-
99
- self .cur = k
100
- inorder(root)
101
- return self .res
70
+ dfs(root.right)
71
+ k -= 1
72
+ if k == 0 :
73
+ ans = root.val
74
+ dfs(root.left)
75
+
76
+ ans = 0
77
+ dfs(root)
78
+ return ans
102
79
```
103
80
104
81
### ** Java**
@@ -114,66 +91,28 @@ class Solution:
114
91
* }
115
92
*/
116
93
class Solution {
117
- private int cur ;
118
- private int res ;
94
+ private int k ;
95
+ private int ans ;
119
96
120
97
public int kthLargest (TreeNode root , int k ) {
121
- cur = k;
122
- res = 0 ;
123
- inorder(root);
124
- return res;
98
+ this . k = k;
99
+ dfs(root);
100
+ return ans;
125
101
}
126
102
127
- private void inorder (TreeNode root ) {
128
- if (root == null ) {
103
+ private void dfs (TreeNode root ) {
104
+ if (root == null || k == 0 ) {
129
105
return ;
130
106
}
131
- inorder(root. right);
132
- -- cur;
133
- if (cur == 0 ) {
134
- res = root. val;
135
- return ;
107
+ dfs(root. right);
108
+ if (-- k == 0 ) {
109
+ ans = root. val;
136
110
}
137
- inorder (root. left);
111
+ dfs (root. left);
138
112
}
139
113
}
140
114
```
141
115
142
- ### ** JavaScript**
143
-
144
- ``` js
145
- /**
146
- * Definition for a binary tree node.
147
- * function TreeNode(val) {
148
- * this.val = val;
149
- * this.left = this.right = null;
150
- * }
151
- */
152
- /**
153
- * @param {TreeNode} root
154
- * @param {number} k
155
- * @return {number}
156
- */
157
- var kthLargest = function (root , k ) {
158
- const inorder = root => {
159
- if (! root) {
160
- return ;
161
- }
162
- inorder (root .right );
163
- -- cur;
164
- if (cur == 0 ) {
165
- res = root .val ;
166
- return ;
167
- }
168
- inorder (root .left );
169
- };
170
- let res = 0 ;
171
- let cur = k;
172
- inorder (root);
173
- return res;
174
- };
175
- ```
176
-
177
116
### ** C++**
178
117
179
118
``` cpp
@@ -189,31 +128,52 @@ var kthLargest = function (root, k) {
189
128
class Solution {
190
129
public:
191
130
int kthLargest(TreeNode* root, int k) {
192
- cur = k;
193
- inorder(root);
194
- return res;
195
- }
196
-
197
- private:
198
- int cur, res;
199
-
200
- void inorder(TreeNode* root) {
201
- if (!root) {
202
- return;
203
- }
204
- inorder (root->right);
205
- --cur;
206
- if (cur == 0) {
207
- res = root->val;
208
- return;
209
- }
210
- inorder(root->left);
131
+ int ans = 0;
132
+ function<void(TreeNode* )> dfs = [ &] (TreeNode* root) {
133
+ if (!root || !k) {
134
+ return;
135
+ }
136
+ dfs(root->right);
137
+ if (--k == 0) {
138
+ ans = root->val;
139
+ }
140
+ dfs(root->left);
141
+ };
142
+ dfs(root);
143
+ return ans;
211
144
}
212
145
};
213
146
```
214
147
215
148
### **Go**
216
149
150
+ ```go
151
+ /**
152
+ * Definition for a binary tree node.
153
+ * type TreeNode struct {
154
+ * Val int
155
+ * Left *TreeNode
156
+ * Right *TreeNode
157
+ * }
158
+ */
159
+ func kthLargest(root *TreeNode, k int) (ans int) {
160
+ var dfs func(*TreeNode)
161
+ dfs = func(root *TreeNode) {
162
+ if root == nil || k == 0 {
163
+ return
164
+ }
165
+ dfs(root.Right)
166
+ k--
167
+ if k == 0 {
168
+ ans = root.Val
169
+ }
170
+ dfs(root.Left)
171
+ }
172
+ dfs(root)
173
+ return
174
+ }
175
+ ```
176
+
217
177
利用 Go 的特性,中序遍历“生产”的数字传到 ` channel ` ,返回第 ` k ` 个。
218
178
219
179
``` go
@@ -249,6 +209,38 @@ func inorder(ctx context.Context, cur *TreeNode, ch chan<- int) {
249
209
}
250
210
```
251
211
212
+ ### ** JavaScript**
213
+
214
+ ``` js
215
+ /**
216
+ * Definition for a binary tree node.
217
+ * function TreeNode(val) {
218
+ * this.val = val;
219
+ * this.left = this.right = null;
220
+ * }
221
+ */
222
+ /**
223
+ * @param {TreeNode} root
224
+ * @param {number} k
225
+ * @return {number}
226
+ */
227
+ var kthLargest = function (root , k ) {
228
+ let ans = 0 ;
229
+ const dfs = root => {
230
+ if (! root || ! k) {
231
+ return ;
232
+ }
233
+ dfs (root .right );
234
+ if (-- k == 0 ) {
235
+ ans = root .val ;
236
+ }
237
+ dfs (root .left );
238
+ };
239
+ dfs (root);
240
+ return ans;
241
+ };
242
+ ```
243
+
252
244
### ** TypeScript**
253
245
254
246
``` ts
@@ -338,21 +330,24 @@ impl Solution {
338
330
* }
339
331
*/
340
332
public class Solution {
333
+ private int ans ;
334
+ private int k ;
335
+
341
336
public int KthLargest (TreeNode root , int k ) {
342
- List < int > list = new List < int >() ;
343
- list = postorder (root , list );
344
- return list [ list . Count () - k ] ;
337
+ this . k = k ;
338
+ dfs (root );
339
+ return ans ;
345
340
}
346
341
347
- public List <int > postorder (TreeNode root , List <int > list ) {
348
- if (root == null ) {
349
- return list ;
350
- } else {
351
- postorder (root .left , list );
352
- list .Add (root .val );
353
- postorder (root .right , list );
342
+ private void dfs (TreeNode root ) {
343
+ if (root == null || k == 0 ) {
344
+ return ;
354
345
}
355
- return list ;
346
+ dfs (root .right );
347
+ if (-- k == 0 ) {
348
+ ans = root .val ;
349
+ }
350
+ dfs (root .left );
356
351
}
357
352
}
358
353
```
0 commit comments