Easy
题目描述
给你一个下标从 0 开始的整数数组 nums,其中 nums[i] 表示第 i 名学生的分数。同时给你一个整数 k。
从数组中选出任意 k 名学生的分数,使得这 k 个分数中最高分和最低分的差值达到最小化。
返回可能的最小差值。
示例 1:
输入:nums = [90], k = 1
输出:0
解释:选出 1 名学生的分数有一种方法:
- [90]。最高分和最低分之间的差值是 90 - 90 = 0 。
可能的最小差值是 0 。
示例 2:
输入: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 <= nums.length <= 10000 <= nums[i] <= 10^5
解题思路
这道题的核心思路是:为了使选出的k个分数中最高分和最低分的差值最小化,我们需要选择彼此尽可能接近的分数。
方法分析:
排序 + 滑动窗口(推荐解法):
- 首先对数组进行排序,使得相近的分数聚集在一起
- 排序后,任意连续的k个分数都是彼此最接近的k个分数
- 使用滑动窗口遍历所有长度为k的连续子数组
- 对每个窗口,计算最大值与最小值的差值(即窗口右端点减去左端点)
- 返回所有窗口中的最小差值
暴力枚举:
- 枚举所有可能的k个分数的组合
- 对每个组合计算最大值与最小值的差值
- 时间复杂度为O(C(n,k) × k),在数据范围较大时效率较低
实现细节:
- 排序后,窗口的最大值就是右端点,最小值就是左端点
- 滑动窗口从索引0开始,到索引n-k结束
- 特殊情况:当k=1时,差值恒为0
代码实现
class Solution {
public:
int minimumDifference(vector<int>& nums, int k) {
if (k == 1) return 0;
sort(nums.begin(), nums.end());
int minDiff = INT_MAX;
for (int i = 0; i <= nums.size() - k; i++) {
minDiff = min(minDiff, nums[i + k - 1] - nums[i]);
}
return minDiff;
}
};
class Solution:
def minimumDifference(self, nums: List[int], k: int) -> int:
if k == 1:
return 0
nums.sort()
min_diff = float('inf')
for i in range(len(nums) - k + 1):
min_diff = min(min_diff, nums[i + k - 1] - nums[i])
return min_diff
public class Solution {
public int MinimumDifference(int[] nums, int k) {
if (k == 1) return 0;
Array.Sort(nums);
int minDiff = int.MaxValue;
for (int i = 0; i <= nums.Length - k; i++) {
minDiff = Math.Min(minDiff, nums[i + k - 1] - nums[i]);
}
return minDiff;
}
}
var minimumDifference = function(nums, k) {
if (k === 1) return 0;
nums.sort((a, b) => a - b);
let minDiff = Infinity;
for (let i = 0; i <= nums.length - k; i++) {
minDiff = Math.min(minDiff, nums[i + k - 1] - nums[i]);
}
return minDiff;
};
复杂度分析
| 复杂度类型 | 大小 | 说明 |
|---|---|---|
| 时间复杂度 | O(n log n) | 主要消耗在排序操作上,滑动窗口遍历为O(n) |
| 空间复杂度 | O(1) | 只使用常数级别的额外空间(不考虑排序的空间消耗) |
相关题目
- . Array Partition (Easy)