|
48 | 48 |
|
49 | 49 | 由于二叉搜索树的性质,中序遍历一定能得到升序序列,因此可以采用中序遍历找出第 k 小的元素。
|
50 | 50 |
|
| 51 | +**方法二:预处理结点数** |
| 52 | + |
| 53 | +预处理每个结点作为根节点的子树的节点数。 |
| 54 | + |
| 55 | +这种算法可以用来优化频繁查找第 k 个树、而二叉搜索树本身不被修改的情况。 |
| 56 | + |
51 | 57 | <!-- tabs:start -->
|
52 | 58 |
|
53 | 59 | ### **Python3**
|
@@ -76,6 +82,47 @@ class Solution:
|
76 | 82 | root = root.right
|
77 | 83 | ```
|
78 | 84 |
|
| 85 | +```python |
| 86 | +# Definition for a binary tree node. |
| 87 | +# class TreeNode: |
| 88 | +# def __init__(self, val=0, left=None, right=None): |
| 89 | +# self.val = val |
| 90 | +# self.left = left |
| 91 | +# self.right = right |
| 92 | + |
| 93 | + |
| 94 | +class BST: |
| 95 | + def __init__(self, root): |
| 96 | + self.cnt = Counter() |
| 97 | + self.root = root |
| 98 | + self.count(root) |
| 99 | + |
| 100 | + def kthSmallest(self, k): |
| 101 | + node = self.root |
| 102 | + while node: |
| 103 | + if self.cnt[node.left] == k - 1: |
| 104 | + return node.val |
| 105 | + if self.cnt[node.left] < k - 1: |
| 106 | + k -= (self.cnt[node.left] + 1) |
| 107 | + node = node.right |
| 108 | + else: |
| 109 | + node = node.left |
| 110 | + return 0 |
| 111 | + |
| 112 | + def count(self, root): |
| 113 | + if root is None: |
| 114 | + return 0 |
| 115 | + n = 1 + self.count(root.left) + self.count(root.right) |
| 116 | + self.cnt[root] = n |
| 117 | + return n |
| 118 | + |
| 119 | + |
| 120 | +class Solution: |
| 121 | + def kthSmallest(self, root: Optional[TreeNode], k: int) -> int: |
| 122 | + bst = BST(root) |
| 123 | + return bst.kthSmallest(k) |
| 124 | +``` |
| 125 | + |
79 | 126 | ### **Java**
|
80 | 127 |
|
81 | 128 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
@@ -116,6 +163,66 @@ class Solution {
|
116 | 163 | }
|
117 | 164 | ```
|
118 | 165 |
|
| 166 | +```java |
| 167 | +/** |
| 168 | + * Definition for a binary tree node. |
| 169 | + * public class TreeNode { |
| 170 | + * int val; |
| 171 | + * TreeNode left; |
| 172 | + * TreeNode right; |
| 173 | + * TreeNode() {} |
| 174 | + * TreeNode(int val) { this.val = val; } |
| 175 | + * TreeNode(int val, TreeNode left, TreeNode right) { |
| 176 | + * this.val = val; |
| 177 | + * this.left = left; |
| 178 | + * this.right = right; |
| 179 | + * } |
| 180 | + * } |
| 181 | + */ |
| 182 | +class Solution { |
| 183 | + public int kthSmallest(TreeNode root, int k) { |
| 184 | + BST bst = new BST(root); |
| 185 | + return bst.kthSmallest(k); |
| 186 | + } |
| 187 | +} |
| 188 | + |
| 189 | +class BST { |
| 190 | + private TreeNode root; |
| 191 | + private Map<TreeNode, Integer> cnt = new HashMap<>(); |
| 192 | + |
| 193 | + public BST(TreeNode root) { |
| 194 | + this.root = root; |
| 195 | + count(root); |
| 196 | + } |
| 197 | + |
| 198 | + public int kthSmallest(int k) { |
| 199 | + TreeNode node = root; |
| 200 | + while (node != null) { |
| 201 | + int v = node.left == null ? 0 : cnt.get(node.left); |
| 202 | + if (v == k - 1) { |
| 203 | + return node.val; |
| 204 | + } |
| 205 | + if (v < k - 1) { |
| 206 | + node = node.right; |
| 207 | + k -= (v + 1); |
| 208 | + } else { |
| 209 | + node = node.left; |
| 210 | + } |
| 211 | + } |
| 212 | + return 0; |
| 213 | + } |
| 214 | + |
| 215 | + private int count(TreeNode root) { |
| 216 | + if (root == null) { |
| 217 | + return 0; |
| 218 | + } |
| 219 | + int n = 1 + count(root.left) + count(root.right); |
| 220 | + cnt.put(root, n); |
| 221 | + return n; |
| 222 | + } |
| 223 | +} |
| 224 | +``` |
| 225 | + |
119 | 226 | ### **C++**
|
120 | 227 |
|
121 | 228 | ```cpp
|
@@ -154,6 +261,61 @@ public:
|
154 | 261 | };
|
155 | 262 | ```
|
156 | 263 |
|
| 264 | +```cpp |
| 265 | +/** |
| 266 | + * Definition for a binary tree node. |
| 267 | + * struct TreeNode { |
| 268 | + * int val; |
| 269 | + * TreeNode *left; |
| 270 | + * TreeNode *right; |
| 271 | + * TreeNode() : val(0), left(nullptr), right(nullptr) {} |
| 272 | + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} |
| 273 | + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} |
| 274 | + * }; |
| 275 | + */ |
| 276 | +class BST { |
| 277 | +public: |
| 278 | + BST(TreeNode* root) : root(root) { |
| 279 | + count(root); |
| 280 | + } |
| 281 | +
|
| 282 | + int kthSmallest(int k) { |
| 283 | + TreeNode* node = root; |
| 284 | + while (node) |
| 285 | + { |
| 286 | + int v = !node->left ? 0 : cnt[node->left]; |
| 287 | + if (v == k - 1) return node->val; |
| 288 | + if (v < k - 1) |
| 289 | + { |
| 290 | + node = node->right; |
| 291 | + k -= (v + 1); |
| 292 | + } |
| 293 | + else node = node->left; |
| 294 | + } |
| 295 | + return 0; |
| 296 | + } |
| 297 | +
|
| 298 | +private: |
| 299 | + TreeNode* root; |
| 300 | + unordered_map<TreeNode*, int> cnt; |
| 301 | + |
| 302 | + int count(TreeNode* root) { |
| 303 | + if (!root) return 0; |
| 304 | + int n = 1 + count(root->left) + count(root->right); |
| 305 | + cnt[root] = n; |
| 306 | + return n; |
| 307 | + } |
| 308 | +}; |
| 309 | +
|
| 310 | +class Solution { |
| 311 | +public: |
| 312 | + int kthSmallest(TreeNode* root, int k) { |
| 313 | + BST bst(root); |
| 314 | + return bst.kthSmallest(k); |
| 315 | + } |
| 316 | +}; |
| 317 | +``` |
| 318 | + |
157 | 319 | ### **Go**
|
158 | 320 |
|
159 | 321 | ```go
|
@@ -185,6 +347,61 @@ func kthSmallest(root *TreeNode, k int) int {
|
185 | 347 | }
|
186 | 348 | ```
|
187 | 349 |
|
| 350 | +```go |
| 351 | +/** |
| 352 | + * Definition for a binary tree node. |
| 353 | + * type TreeNode struct { |
| 354 | + * Val int |
| 355 | + * Left *TreeNode |
| 356 | + * Right *TreeNode |
| 357 | + * } |
| 358 | + */ |
| 359 | +type BST struct { |
| 360 | + cnt map[*TreeNode]int |
| 361 | + root *TreeNode |
| 362 | +} |
| 363 | + |
| 364 | +func newBST(root *TreeNode) *BST { |
| 365 | + var count func(*TreeNode) int |
| 366 | + cnt := map[*TreeNode]int{} |
| 367 | + count = func(root *TreeNode) int { |
| 368 | + if root == nil { |
| 369 | + return 0 |
| 370 | + } |
| 371 | + n := 1 + count(root.Left) + count(root.Right) |
| 372 | + cnt[root] = n |
| 373 | + return n |
| 374 | + } |
| 375 | + count(root) |
| 376 | + return &BST{cnt, root} |
| 377 | +} |
| 378 | + |
| 379 | +func (bst *BST) kthSmallest(k int) int { |
| 380 | + node := bst.root |
| 381 | + for node != nil { |
| 382 | + v := 0 |
| 383 | + if node.Left != nil { |
| 384 | + v = bst.cnt[node.Left] |
| 385 | + } |
| 386 | + if v == k-1 { |
| 387 | + return node.Val |
| 388 | + } |
| 389 | + if v < k-1 { |
| 390 | + k -= (v + 1) |
| 391 | + node = node.Right |
| 392 | + } else { |
| 393 | + node = node.Left |
| 394 | + } |
| 395 | + } |
| 396 | + return 0 |
| 397 | +} |
| 398 | + |
| 399 | +func kthSmallest(root *TreeNode, k int) int { |
| 400 | + bst := newBST(root) |
| 401 | + return bst.kthSmallest(k) |
| 402 | +} |
| 403 | +``` |
| 404 | + |
188 | 405 | ### **TypeScript**
|
189 | 406 |
|
190 | 407 | ```ts
|
|
0 commit comments