1. 问题背景与核心思路
这道题目要求我们从给定的学生分数数组中,选取k个分数,使得这k个分数中的最大值与最小值之差(即极差)最小。这是一个典型的数组处理问题,关键在于如何高效地找到最优解。
1.1 问题重述
给定一个整数数组nums表示学生分数,和一个整数k。我们需要:
- 从nums中选出k个元素
- 计算这k个元素的最大值与最小值之差
- 找到所有可能的k个元素组合中,差值最小的那个
1.2 直观解法分析
最直观的解法是枚举所有可能的k个元素的组合,计算每个组合的极差,然后取最小值。这种方法的时间复杂度是O(C(n,k)),当n和k较大时,这种组合爆炸的方式显然不可行。
注意:当n=1000,k=500时,组合数C(1000,500)≈2.7×10^299,这在实际中根本无法计算。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 优化思路:排序+滑动窗口
2.1 为什么排序是关键
排序是这个解法中最关键的一步。通过将数组排序,我们可以利用有序性来简化问题:
- 在有序数组中,数值相近的元素会聚集在一起
- 要获得最小极差,最优解必然由连续的k个元素组成
- 这样我们只需要考虑所有连续的k个元素的窗口,而不必考虑所有可能的组合
2.2 滑动窗口的应用
排序后,我们可以使用滑动窗口技术来高效地遍历所有可能的k个连续元素:
- 窗口大小固定为k
- 窗口从左到右滑动
- 在每个窗口位置计算nums[right] - nums[left]
- 记录所有窗口中的最小差值
这种方法的优势在于:
- 排序时间复杂度O(nlogn)
- 滑动窗口遍历时间复杂度O(n)
- 总体时间复杂度由排序决定,为O(nlogn)
3. 算法实现细节
3.1 完整代码解析
java复制import java.util.Arrays;
class Solution {
public int minimumDifference(int[] nums, int k) {
// 1. 排序数组
Arrays.sort(nums);
// 初始化结果为最大整数值
int ans = Integer.MAX_VALUE;
