1984. 学生分数的最小差值 : 排序 + 滑动窗口运用题

简介: 1984. 学生分数的最小差值 : 排序 + 滑动窗口运用题

网络异常,图片无法展示
|


题目描述



这是 LeetCode 上的 1984. 学生分数的最小差值 ,难度为 简单


Tag : 「二分」、「滑动窗口」


给你一个 下标从 00 开始 的整数数组 numsnums ,其中 nums[i]nums[i] 表示第 ii 名学生的分数。另给你一个整数 kk


从数组中选出任意 kk 名学生的分数,使这 kk 个分数间 最高分最低分 的 差值 达到 最小化 。


返回可能的 最小差值


示例 1:


输入:nums = [90], k = 1
输出:0
解释:选出 1 名学生的分数,仅有 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 <= 10001<=k<=nums.length<=1000
  • 0 <= nums[i] <= 10^50<=nums[i]<=105


排序 + 滑动窗口



nn 个元素里找 kk 个,使得 kk 个元素最大差值最小。


最大值最小化问题容易想到「二分」,利用答案本身具有「二段性」,来将原本的求解问题转化为判断定问题。


回到本题,容易证明,这 kk 个元素必然是有序数组中(排序后)的连续段。反证法,若最佳 kk 个选择不是连续段,能够调整为连续段,结果不会变差。


因此我们可以先对 numsnums 进行排序,然后扫描所有大小为 kk 的窗口,直接找到答案,而无须使用「二分」。


代码(二分答案代码见 P2P2):


class Solution {
    public int minimumDifference(int[] nums, int k) {
        Arrays.sort(nums);
        int n = nums.length, ans = nums[k - 1] - nums[0];
        for (int i = k; i < n; i++) {
            ans = Math.min(ans, nums[i] - nums[i - k + 1]);
        }
        return ans;
    }
}
复制代码

class Solution {
    int[] nums; int k;
    public int minimumDifference(int[] _nums, int _k) {
        nums = _nums; k = _k;
        Arrays.sort(nums);
        int l = 0, r = 100010;
        while (l < r) {
            int mid = l + r >> 1;
            if (check(mid)) r = mid;
            else l = mid + 1;
        }
        return r;
    }
    boolean check(int x) {
        int n = nums.length, ans = nums[k - 1] - nums[0];
        for (int i = k; i < n && ans > x; i++) {
            ans = Math.min(ans, nums[i] - nums[i - k + 1]);
        }
        return ans <= x;
    }
}
复制代码


  • 时间复杂度:排序复杂度为 O(n\log{n})O(nlogn);遍历得到答案复杂度为 O(n)O(n)。整体复杂度为 O(n\log{n})O(nlogn)
  • 空间复杂度:O(\log{n})O(logn)


最后



这是我们「刷穿 LeetCode」系列文章的第 No.1894 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
|
7月前
|
算法 测试技术 C#
C++前缀和算法的应用:统计得分小于K的子数组数目
C++前缀和算法的应用:统计得分小于K的子数组数目
|
2月前
|
算法 测试技术 C#
【线段树】2276. 统计区间中的整数数目
【线段树】2276. 统计区间中的整数数目
|
2月前
|
算法 测试技术 C#
二分查找|前缀和|滑动窗口|2302:统计得分小于 K 的子数组数目
二分查找|前缀和|滑动窗口|2302:统计得分小于 K 的子数组数目
|
2月前
|
算法 测试技术 C#
【map】【滑动窗口】C++算法:最小区间
【map】【滑动窗口】C++算法:最小区间
|
2月前
leetcode:908. 最小差值 I
leetcode:908. 最小差值 I
19 0
|
2月前
|
算法 测试技术 C#
【滑动窗口】【差分数组】C++算法:K 连续位的最小翻转次数
【滑动窗口】【差分数组】C++算法:K 连续位的最小翻转次数
|
2月前
leetcode-1984:学生分数的最小差值
leetcode-1984:学生分数的最小差值
28 0
|
7月前
|
机器学习/深度学习 算法 测试技术
C++二分算法: 找出第 K 小的数对距离
C++二分算法: 找出第 K 小的数对距离
|
12月前
|
Cloud Native Go
801. 使序列递增的最小交换次数:动态规划
这是 力扣上的 801. 使序列递增的最小交换次数,难度为 困难。
|
算法 JavaScript
辛辣天塞!滑动窗口之【和的最大值】&【最大值集合】
本篇带来两道经典的关于滑动窗口的算法题,有兴趣可在控制台跑一跑~

热门文章

最新文章

  • 1
    流量控制系统,用正则表达式提取汉字
    25
  • 2
    Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
    26
  • 3
    Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
    25
  • 4
    Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
    27
  • 5
    S外部函数可以访问函数内部的变量的闭包-闭包最简单的用不了,闭包是内层函数+外层函数的变量,简称为函数套函数,外部函数可以访问函数内部的变量,存在函数套函数
    23
  • 6
    Redis06-Redis常用的命令,模糊的搜索查询往往会对服务器产生很大的压力,MSET k1 v1 k2 v2 k3 v3 添加,DEL是删除的意思,EXISTS age 可以用来查询是否有存在1
    30
  • 7
    Redis05数据结构介绍,数据结构介绍,官方网站中看到
    21
  • 8
    JS字符串数据类型转换,字符串如何转成变量,+号只要有一个是字符串,就会把另外一个转成字符串,- * / 都会把数据转成数字类型,数字型控制台是蓝色,字符型控制台是黑色,
    19
  • 9
    JS数组操作---删除,arr.pop()方法从数组中删除最后一个元素,并返回该元素的值,arr.shift() 删除第一个值,arr.splice()方法,删除指定元素,arr.splice,从第一
    19
  • 10
    定义好变量,${age}模版字符串,对象可以放null,检验数据类型console.log(typeof str)
    19