Skip to content

Commit

Permalink
feat: 添加二叉搜索树的第 k 大的节点 (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
xyxiao001 authored Aug 20, 2021
1 parent 6cdabc4 commit 3f2c58f
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions src/book3/algorithm-binary-tree-k.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 二叉搜索树的第 k 大的节点

## 题目描述

给定一棵二叉搜索树,请找出其中第 k 大的节点。

示例 1:

```
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
```

示例 2:

```
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4
```

## 解题基本知识

二叉搜索树(Binary Search Tree)又名二叉查找树、二叉排序树。它是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

## 解法

[在线链接](https://codesandbox.io/s/erchasousuoshudedi-k-dadejiedian-vfpbh?file=/index.html)

利用二叉搜索树的特性进行中序遍历。先遍历左节点,然后根节点,最后遍历右节点,得到的是一个递增序列,那么序列的倒序为递减序列。因此这道题我们可以转变为求二叉搜索树中序遍历倒序的第 k 个数。

![解法图示](https://user-images.githubusercontent.com/15681693/130164388-85e96093-9336-4174-b139-59e83d972a20.png)

```javascript
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
const kthLargest = (root, k) => {
let res = null; // 初始化返回值
// 因为需要倒序第 k 个,所以处理是右节点,根节点,然后左节点
const dfs = (root) => {
if (!root) return; // 如果当前节点为 null,本轮处理结束
dfs(root.right); // 开始处理右节点
if (k === 0) return; // k 值 为 0,代表已经处理的节点超过目标节点,本轮处理结束
if (--k === 0) {
// 当 k 值 减 1 为 0,表示已经到了我们想要的 k 大 节点,保存当前值
res = root.val;
}
dfs(root.left); // 处理左节点
};
dfs(root); // 从初始化节点开始处理
return res;
};
```

### 复杂度分析:

- 时间复杂度 O(N):无论 k 的值大小,递归深度都为 N,占用 O(N) 时间。
- 空间复杂度 O(N):无论 k 的值大小,递归深度都为 N,占用 O(N) 空间。

### 参考资料

1. [剑指 offer](https://book.douban.com/subject/6966465/)

0 comments on commit 3f2c58f

Please sign in to comment.