-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
326 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# [0783. 二叉搜索树节点最小距离](https://leetcode.cn/problems/minimum-distance-between-bst-nodes/) | ||
|
||
- 标签:树、深度优先搜索、广度优先搜索、二叉搜索树、二叉树 | ||
- 难度:简单 | ||
|
||
## 题目链接 | ||
|
||
- [0783. 二叉搜索树节点最小距离 - 力扣](https://leetcode.cn/problems/minimum-distance-between-bst-nodes/) | ||
|
||
## 题目大意 | ||
|
||
**描述**:给定一个二叉搜索树的根节点 $root$。 | ||
|
||
**要求**:返回树中任意两不同节点值之间的最小差值。 | ||
|
||
**说明**: | ||
|
||
- **差值**:是一个正数,其数值等于两值之差的绝对值。 | ||
- 树中节点的数目范围是 $[2, 100]$。 | ||
- $0 \le Node.val \le 10^5$。 | ||
|
||
**示例**: | ||
|
||
- 示例 1: | ||
|
||
![](https://assets.leetcode.com/uploads/2021/02/05/bst1.jpg) | ||
|
||
```python | ||
输入:root = [4,2,6,1,3] | ||
输出:1 | ||
``` | ||
|
||
- 示例 2: | ||
|
||
![](https://assets.leetcode.com/uploads/2021/02/05/bst2.jpg) | ||
|
||
```python | ||
输入:root = [1,0,48,null,null,12,49] | ||
输出:1 | ||
``` | ||
|
||
## 解题思路 | ||
|
||
### 思路 1:中序遍历 | ||
|
||
先来看二叉搜索树的定义: | ||
|
||
- 若左子树不为空,则左子树上所有节点值均小于它的根节点值; | ||
- 若右子树不为空,则右子树上所有节点值均大于它的根节点值; | ||
- 任意节点的左、右子树也分别为二叉搜索树。 | ||
|
||
题目要求二叉搜索树上任意两节点的差的绝对值的最小值。 | ||
|
||
二叉树的中序遍历顺序是:左 -> 根 -> 右,二叉搜索树的中序遍历最终得到就是一个升序数组。而升序数组中绝对值差的最小值就是比较相邻两节点差值的绝对值,找出其中最小值。 | ||
|
||
那么我们就可以先对二叉搜索树进行中序遍历,并保存中序遍历的结果。然后再比较相邻节点差值的最小值,从而找出最小值。 | ||
|
||
### 思路 1:代码 | ||
|
||
```Python | ||
# Definition for a binary tree node. | ||
# class TreeNode: | ||
# def __init__(self, val=0, left=None, right=None): | ||
# self.val = val | ||
# self.left = left | ||
# self.right = right | ||
class Solution: | ||
def inorderTraversal(self, root: TreeNode) -> List[int]: | ||
res = [] | ||
def inorder(root): | ||
if not root: | ||
return | ||
inorder(root.left) | ||
res.append(root.val) | ||
inorder(root.right) | ||
|
||
inorder(root) | ||
return res | ||
|
||
def minDiffInBST(self, root: Optional[TreeNode]) -> int: | ||
inorder = self.inorderTraversal(root) | ||
ans = float('inf') | ||
for i in range(1, len(inorder)): | ||
ans = min(ans, abs(inorder[i - 1] - inorder[i])) | ||
|
||
return ans | ||
``` | ||
|
||
### 思路 1:复杂度分析 | ||
|
||
- **时间复杂度**:$O(n)$,其中 $n$ 为二叉搜索树中的节点数量。 | ||
- **空间复杂度**:$O(n)$。 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
- [1338. 数组大小减半](https://leetcode.cn/problems/reduce-array-size-to-the-half/) | ||
|
||
- 标签:贪心、数组、哈希表、排序、堆(优先队列) | ||
- 难度:中等 | ||
|
||
## 题目链接 | ||
|
||
- [1338. 数组大小减半 - 力扣](https://leetcode.cn/problems/reduce-array-size-to-the-half/) | ||
|
||
## 题目大意 | ||
|
||
**描述**:给定过一个整数数组 $arr$。你可以从中选出一个整数集合,并在数组 $arr$ 删除所有整数集合对应的数。 | ||
|
||
**要求**:返回至少能删除数组中的一半整数的整数集合的最小大小。 | ||
|
||
**说明**: | ||
|
||
- $1 \le arr.length \le 10^5$。 | ||
- $arr.length$ 为偶数。 | ||
- $1 \le arr[i] \le 10^5$。 | ||
|
||
**示例**: | ||
|
||
- 示例 1: | ||
|
||
```python | ||
输入:arr = [3,3,3,3,5,5,5,2,2,7] | ||
输出:2 | ||
解释:选择 {3,7} 使得结果数组为 [5,5,5,2,2]、长度为 5(原数组长度的一半)。 | ||
大小为 2 的可行集合有 {3,5},{3,2},{5,2}。 | ||
选择 {2,7} 是不可行的,它的结果数组为 [3,3,3,3,5,5,5],新数组长度大于原数组的二分之一。 | ||
``` | ||
|
||
- 示例 2: | ||
|
||
```python | ||
输入:arr = [7,7,7,7,7,7] | ||
输出:1 | ||
解释:我们只能选择集合 {7},结果数组为空。 | ||
``` | ||
|
||
## 解题思路 | ||
|
||
### 思路 1:贪心算法 | ||
|
||
对于选出的整数集合中每一个数 $x$ 来说,我们会删除数组 $arr$ 中所有值为 $x$ 的整数。 | ||
|
||
因为题目要求我们选出的整数集合最小,所以在每一次选择整数 $x$ 加入整数集合时,我们都应该选择数组 $arr$ 中出现次数最多的数。 | ||
|
||
因此,我们可以统计出数组 $arr$ 中每个整数的出现次数,用哈希表存储,并依照出现次数进行降序排序。 | ||
|
||
然后,依次选择出现次数最多的数进行删除,并统计个数,直到删除了至少一半的数时停止。 | ||
|
||
最后,将统计个数作为答案返回。 | ||
|
||
### 思路 1:代码 | ||
|
||
```Python | ||
class Solution: | ||
def minSetSize(self, arr: List[int]) -> int: | ||
cnts = Counter(arr) | ||
ans, cnt = 0, 0 | ||
for num, freq in cnts.most_common(): | ||
cnt += freq | ||
ans += 1 | ||
if cnt * 2 >= len(arr): | ||
break | ||
|
||
return ans | ||
``` | ||
|
||
### 思路 1:复杂度分析 | ||
|
||
- **时间复杂度**:$O(n \times \log n)$,其中 $n$ 为数组 $arr$ 的长度。 | ||
- **空间复杂度**:$O(n)$。 | ||
|
Oops, something went wrong.