diff --git a/Contents/00.Introduction/04.Solutions-List.md b/Contents/00.Introduction/04.Solutions-List.md index f2f33c1a..61d27926 100644 --- a/Contents/00.Introduction/04.Solutions-List.md +++ b/Contents/00.Introduction/04.Solutions-List.md @@ -1,4 +1,4 @@ -# LeetCode 题解(已完成 823 道) +# LeetCode 题解(已完成 827 道) | 题号 | 标题 | 题解 | 标签 | 难度 | | :------ | :------ | :------ | :------ | :------ | @@ -414,6 +414,7 @@ | 0771 | [宝石与石头](https://leetcode.cn/problems/jewels-and-stones/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0771.%20%E5%AE%9D%E7%9F%B3%E4%B8%8E%E7%9F%B3%E5%A4%B4.md) | 哈希表、字符串 | 简单 | | 0778 | [水位上升的泳池中游泳](https://leetcode.cn/problems/swim-in-rising-water/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0778.%20%E6%B0%B4%E4%BD%8D%E4%B8%8A%E5%8D%87%E7%9A%84%E6%B3%B3%E6%B1%A0%E4%B8%AD%E6%B8%B8%E6%B3%B3.md) | 深度优先搜索、广度优先搜索、并查集、数组、二分查找、矩阵、堆(优先队列) | 困难 | | 0779 | [第K个语法符号](https://leetcode.cn/problems/k-th-symbol-in-grammar/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0779.%20%E7%AC%ACK%E4%B8%AA%E8%AF%AD%E6%B3%95%E7%AC%A6%E5%8F%B7.md) | 位运算、递归、数学 | 中等 | +| 0783 | [二叉搜索树节点最小距离](https://leetcode.cn/problems/minimum-distance-between-bst-nodes/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0783.%20%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E8%8A%82%E7%82%B9%E6%9C%80%E5%B0%8F%E8%B7%9D%E7%A6%BB.md) | 树、深度优先搜索、广度优先搜索、二叉搜索树、二叉树 | 简单 | | 0784 | [字母大小写全排列](https://leetcode.cn/problems/letter-case-permutation/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0784.%20%E5%AD%97%E6%AF%8D%E5%A4%A7%E5%B0%8F%E5%86%99%E5%85%A8%E6%8E%92%E5%88%97.md) | 位运算、字符串、回溯 | 中等 | | 0785 | [判断二分图](https://leetcode.cn/problems/is-graph-bipartite/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0785.%20%E5%88%A4%E6%96%AD%E4%BA%8C%E5%88%86%E5%9B%BE.md) | 深度优先搜索、广度优先搜索、并查集、图 | 中等 | | 0788 | [旋转数字](https://leetcode.cn/problems/rotated-digits/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0788.%20%E6%97%8B%E8%BD%AC%E6%95%B0%E5%AD%97.md) | 数学、动态规划 | 中等 | @@ -507,6 +508,7 @@ | 1039 | [多边形三角剖分的最低得分](https://leetcode.cn/problems/minimum-score-triangulation-of-polygon/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1039.%20%E5%A4%9A%E8%BE%B9%E5%BD%A2%E4%B8%89%E8%A7%92%E5%89%96%E5%88%86%E7%9A%84%E6%9C%80%E4%BD%8E%E5%BE%97%E5%88%86.md) | 数组、动态规划 | 中等 | | 1047 | [删除字符串中的所有相邻重复项](https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1047.%20%E5%88%A0%E9%99%A4%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E7%9B%B8%E9%82%BB%E9%87%8D%E5%A4%8D%E9%A1%B9.md) | 栈、字符串 | 简单 | | 1049 | [最后一块石头的重量 II](https://leetcode.cn/problems/last-stone-weight-ii/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1049.%20%E6%9C%80%E5%90%8E%E4%B8%80%E5%9D%97%E7%9F%B3%E5%A4%B4%E7%9A%84%E9%87%8D%E9%87%8F%20II.md) | 数组、动态规划 | 中等 | +| 1051 | [高度检查器](https://leetcode.cn/problems/height-checker/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1051.%20%E9%AB%98%E5%BA%A6%E6%A3%80%E6%9F%A5%E5%99%A8.md) | 数组、计数排序、排序 | 简单 | | 1052 | [爱生气的书店老板](https://leetcode.cn/problems/grumpy-bookstore-owner/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1052.%20%E7%88%B1%E7%94%9F%E6%B0%94%E7%9A%84%E4%B9%A6%E5%BA%97%E8%80%81%E6%9D%BF.md) | 数组、滑动窗口 | 中等 | | 1065 | [字符串的索引对](https://leetcode.cn/problems/index-pairs-of-a-string/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1065.%20%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E7%B4%A2%E5%BC%95%E5%AF%B9.md) | 字典树、数组、字符串、排序 | 简单 | | 1079 | [活字印刷](https://leetcode.cn/problems/letter-tile-possibilities/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1079.%20%E6%B4%BB%E5%AD%97%E5%8D%B0%E5%88%B7.md) | 哈希表、字符串、回溯、计数 | 中等 | @@ -547,6 +549,7 @@ | 1310 | [子数组异或查询](https://leetcode.cn/problems/xor-queries-of-a-subarray/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1310.%20%E5%AD%90%E6%95%B0%E7%BB%84%E5%BC%82%E6%88%96%E6%9F%A5%E8%AF%A2.md) | 位运算、数组、前缀和 | 中等 | | 1317 | [将整数转换为两个无零整数的和](https://leetcode.cn/problems/convert-integer-to-the-sum-of-two-no-zero-integers/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1317.%20%E5%B0%86%E6%95%B4%E6%95%B0%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%B8%A4%E4%B8%AA%E6%97%A0%E9%9B%B6%E6%95%B4%E6%95%B0%E7%9A%84%E5%92%8C.md) | 数学 | 简单 | | 1319 | [连通网络的操作次数](https://leetcode.cn/problems/number-of-operations-to-make-network-connected/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1319.%20%E8%BF%9E%E9%80%9A%E7%BD%91%E7%BB%9C%E7%9A%84%E6%93%8D%E4%BD%9C%E6%AC%A1%E6%95%B0.md) | 深度优先搜索、广度优先搜索、并查集、图 | 中等 | +| 1338 | [数组大小减半](https://leetcode.cn/problems/reduce-array-size-to-the-half/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1338.%20%E6%95%B0%E7%BB%84%E5%A4%A7%E5%B0%8F%E5%87%8F%E5%8D%8A.md) | 贪心、数组、哈希表、排序、堆(优先队列) | 中等 | | 1343 | [大小为 K 且平均值大于等于阈值的子数组数目](https://leetcode.cn/problems/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1343.%20%E5%A4%A7%E5%B0%8F%E4%B8%BA%20K%20%E4%B8%94%E5%B9%B3%E5%9D%87%E5%80%BC%E5%A4%A7%E4%BA%8E%E7%AD%89%E4%BA%8E%E9%98%88%E5%80%BC%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84%E6%95%B0%E7%9B%AE.md) | 数组、滑动窗口 | 中等 | | 1349 | [参加考试的最大学生数](https://leetcode.cn/problems/maximum-students-taking-exam/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1349.%20%E5%8F%82%E5%8A%A0%E8%80%83%E8%AF%95%E7%9A%84%E6%9C%80%E5%A4%A7%E5%AD%A6%E7%94%9F%E6%95%B0.md) | 位运算、数组、动态规划、状态压缩、矩阵 | 困难 | | 1358 | [包含所有三种字符的子字符串数目](https://leetcode.cn/problems/number-of-substrings-containing-all-three-characters/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1358.%20%E5%8C%85%E5%90%AB%E6%89%80%E6%9C%89%E4%B8%89%E7%A7%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%9B%AE.md) | 哈希表、字符串、滑动窗口 | 中等 | @@ -608,6 +611,7 @@ | 1929 | [数组串联](https://leetcode.cn/problems/concatenation-of-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1929.%20%E6%95%B0%E7%BB%84%E4%B8%B2%E8%81%94.md) | 数组 | 简单 | | 1941 | [检查是否所有字符出现次数相同](https://leetcode.cn/problems/check-if-all-characters-have-equal-number-of-occurrences/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1941.%20%E6%A3%80%E6%9F%A5%E6%98%AF%E5%90%A6%E6%89%80%E6%9C%89%E5%AD%97%E7%AC%A6%E5%87%BA%E7%8E%B0%E6%AC%A1%E6%95%B0%E7%9B%B8%E5%90%8C.md) | 哈希表、字符串、计数 | 简单 | | 1947 | [最大兼容性评分和](https://leetcode.cn/problems/maximum-compatibility-score-sum/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1947.%20%E6%9C%80%E5%A4%A7%E5%85%BC%E5%AE%B9%E6%80%A7%E8%AF%84%E5%88%86%E5%92%8C.md) | 位运算、数组、动态规划、回溯、状态压缩 | 中等 | +| 1984 | [学生分数的最小差值](https://leetcode.cn/problems/minimum-difference-between-highest-and-lowest-of-k-scores/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1984.%20%E5%AD%A6%E7%94%9F%E5%88%86%E6%95%B0%E7%9A%84%E6%9C%80%E5%B0%8F%E5%B7%AE%E5%80%BC.md) | 数组、排序、滑动窗口 | 简单 | | 1986 | [完成任务的最少工作时间段](https://leetcode.cn/problems/minimum-number-of-work-sessions-to-finish-the-tasks/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1986.%20%E5%AE%8C%E6%88%90%E4%BB%BB%E5%8A%A1%E7%9A%84%E6%9C%80%E5%B0%91%E5%B7%A5%E4%BD%9C%E6%97%B6%E9%97%B4%E6%AE%B5.md) | 位运算、数组、动态规划、回溯、状态压缩 | 中等 | | 1991 | [找到数组的中间位置](https://leetcode.cn/problems/find-the-middle-index-in-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1991.%20%E6%89%BE%E5%88%B0%E6%95%B0%E7%BB%84%E7%9A%84%E4%B8%AD%E9%97%B4%E4%BD%8D%E7%BD%AE.md) | 数组、前缀和 | 简单 | | 1994 | [好子集的数目](https://leetcode.cn/problems/the-number-of-good-subsets/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1994.%20%E5%A5%BD%E5%AD%90%E9%9B%86%E7%9A%84%E6%95%B0%E7%9B%AE.md) | 位运算、数组、数学、动态规划、状态压缩 | 困难 | diff --git a/README.md b/README.md index c50b2ac7..6c64d5d7 100644 --- a/README.md +++ b/README.md @@ -255,4 +255,4 @@ - [动态规划优化题目](./Contents/10.Dynamic-Programming/11.DP-Optimization/04.DP-Optimization-List.md) ## 11. 附加内容 -## [12. LeetCode 题解(已完成 823 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file +## [12. LeetCode 题解(已完成 827 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file diff --git "a/Solutions/0530. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.md" "b/Solutions/0530. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.md" index d0b56bea..89abd0de 100644 --- "a/Solutions/0530. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.md" +++ "b/Solutions/0530. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\346\234\200\345\260\217\347\273\235\345\257\271\345\267\256.md" @@ -9,10 +9,40 @@ ## 题目大意 -给定一棵所有节点都为非负值的二叉搜索树,计算树中任意两节点的差的绝对值的最小值。 +**描述**:给定一个二叉搜索树的根节点 $root$。 + +**要求**:返回树中任意两不同节点值之间的最小差值。 + +**说明**: + +- **差值**:是一个正数,其数值等于两值之差的绝对值。 +- 树中节点的数目范围是 $[2, 10^4]$。 +- $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:中序遍历 + 先来看二叉搜索树的定义: - 若左子树不为空,则左子树上所有节点值均小于它的根节点值; @@ -23,24 +53,41 @@ 二叉树的中序遍历顺序是:左 -> 根 -> 右,二叉搜索树的中序遍历最终得到就是一个升序数组。而升序数组中绝对值差的最小值就是比较相邻两节点差值的绝对值,找出其中最小值。 -那么我们就可以在中序遍历的同时,比较搜索二叉树相邻节点的差值绝对值大小。这就需要维护两个变量:`ans` 和 `pre`。`ans` 用于存储差的绝对值的最小值,`pre`用于保存上一节点的值,用于和当前节点计算差值的绝对值。 +那么我们就可以先对二叉搜索树进行中序遍历,并保存中序遍历的结果。然后再比较相邻节点差值的最小值,从而找出最小值。 -## 代码 +### 思路 1:代码 -```python +```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: - ans = 999 - pre = 999 - def dfs(self, root: TreeNode): - if not root: - return - self.dfs(root.left) - self.ans = min(self.ans, abs(self.pre - root.val)) - self.pre = root.val - self.dfs(root.right) - - def getMinimumDifference(self, root: TreeNode) -> int: - self.dfs(root) - return self.ans + 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 getMinimumDifference(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)$。 + diff --git "a/Solutions/0783. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\212\202\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.md" "b/Solutions/0783. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\212\202\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.md" new file mode 100644 index 00000000..e9b10bfa --- /dev/null +++ "b/Solutions/0783. \344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\212\202\347\202\271\346\234\200\345\260\217\350\267\235\347\246\273.md" @@ -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)$。 + diff --git "a/Solutions/1338. \346\225\260\347\273\204\345\244\247\345\260\217\345\207\217\345\215\212.md" "b/Solutions/1338. \346\225\260\347\273\204\345\244\247\345\260\217\345\207\217\345\215\212.md" new file mode 100644 index 00000000..84221d8f --- /dev/null +++ "b/Solutions/1338. \346\225\260\347\273\204\345\244\247\345\260\217\345\207\217\345\215\212.md" @@ -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)$。 + diff --git "a/Solutions/1984. \345\255\246\347\224\237\345\210\206\346\225\260\347\232\204\346\234\200\345\260\217\345\267\256\345\200\274.md" "b/Solutions/1984. \345\255\246\347\224\237\345\210\206\346\225\260\347\232\204\346\234\200\345\260\217\345\267\256\345\200\274.md" new file mode 100644 index 00000000..48b819a5 --- /dev/null +++ "b/Solutions/1984. \345\255\246\347\224\237\345\210\206\346\225\260\347\232\204\346\234\200\345\260\217\345\267\256\345\200\274.md" @@ -0,0 +1,87 @@ +# [1984. 学生分数的最小差值](https://leetcode.cn/problems/minimum-difference-between-highest-and-lowest-of-k-scores/) + +- 标签:数组、排序、滑动窗口 +- 难度:简单 + +## 题目链接 + +- [1984. 学生分数的最小差值 - 力扣](https://leetcode.cn/problems/minimum-difference-between-highest-and-lowest-of-k-scores/) + +## 题目大意 + +**描述**:给定一个下标从 $0$ 开始的整数数组 $nums$,其中 $nums[i]$ 表示第 $i$ 名学生的分数。另给定一个整数 $k$。 + +**要求**:从数组中选出任意 $k$ 名学生的分数,使这 $k$ 个分数间最高分和最低分的差值达到最小化。返回可能的最小差值 。 + +**说明**: + +- $1 \le k \le nums.length \le 1000$。 +- $0 \le nums[i] \le 10^5$。 + +**示例**: + +- 示例 1: + +```python +输入:nums = [90], k = 1 +输出:0 +解释:选出 1 名学生的分数,仅有 1 种方法: +- [90] 最高分和最低分之间的差值是 90 - 90 = 0 +可能的最小差值是 0 +``` + +- 示例 2: + +```python +输入:nums = [9,4,1,7], k = 2 +输出:2 +解释:选出 2 名学生的分数,有 6 种方法: +- [9,4,1,7] 最高分和最低分之间的差值是 9 - 4 = 5 +- [9,4,1,7] 最高分和最低分之间的差值是 9 - 1 = 8 +- [9,4,1,7] 最高分和最低分之间的差值是 9 - 7 = 2 +- [9,4,1,7] 最高分和最低分之间的差值是 4 - 1 = 3 +- [9,4,1,7] 最高分和最低分之间的差值是 7 - 4 = 3 +- [9,4,1,7] 最高分和最低分之间的差值是 7 - 1 = 6 +可能的最小差值是 2 +``` + +## 解题思路 + +### 思路 1:排序 + 滑动窗口 + +如果想要最小化选择的 $k$ 名学生中最高分与最低分的差值,我们应该在排序后的数组中连续选择 $k$ 名学生。这是因为如果将连续 $k$ 名学生中的某位学生替换成不连续的学生,其最高分 / 最低分一定会发生变化,并且一定会使最高分变得最高 / 最低分变得最低。从而导致差值增大。 + +因此,最优方案一定是在排序后的数组中连续选择 $k$ 名学生中的所有情况中的其中一种。 + +这样,我们可以先对数组 $nums$ 进行升序排序。然后使用一个固定长度为 $k$ 的滑动窗口计算连续选择 $k$ 名学生的最高分与最低分的差值。并记录下最小的差值 $ans$,最后作为答案并返回结果。 + +### 思路 1:代码 + +```Python +class Solution: + def minimumDifference(self, nums: List[int], k: int) -> int: + nums.sort() + ans = float('inf') + for i in range(k - 1, len(nums)): + ans = min(ans, nums[i] - nums[i - k + 1]) + + return ans +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n \times \log n)$,其中 $n$ 为数组 $nums$ 的长度。 +- **空间复杂度**:$O(1)$。 + +### 思路 2: + +### 思路 2:代码 + +```python +``` + +### 思路 2:复杂度分析 + +- **时间复杂度**: +- **空间复杂度**: +