侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 674 篇文章
  • 累计创建 128 个标签
  • 累计收到 20 条评论

目 录CONTENT

文章目录

【模拟, 排序】划分数组使最大差为 K

GabrielxD
2022-06-05 / 0 评论 / 0 点赞 / 127 阅读 / 840 字
温馨提示:
本文最后更新于 2022-07-26,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

6091. 划分数组使最大差为 K


给你一个整数数组 nums 和一个整数 k 。你可以将 nums 划分成一个或多个 子序列 ,使 nums 中的每个元素都 恰好 出现在一个子序列中。

在满足每个子序列中最大值和最小值之间的差值最多为 k 的前提下,返回需要划分的 最少 子序列数目。

子序列 本质是一个序列,可以通过删除另一个序列中的某些元素(或者不删除)但不改变剩下元素的顺序得到。

示例 1:

输入:nums = [3,6,1,2,5], k = 2
输出:2
解释:
可以将 nums 划分为两个子序列 [3,1,2] 和 [6,5] 。
第一个子序列中最大值和最小值的差值是 3 - 1 = 2 。
第二个子序列中最大值和最小值的差值是 6 - 5 = 1 。
由于创建了两个子序列,返回 2 。可以证明需要划分的最少子序列数目就是 2 。

示例 2:

输入:nums = [1,2,3], k = 1
输出:2
解释:
可以将 nums 划分为两个子序列 [1,2] 和 [3] 。
第一个子序列中最大值和最小值的差值是 2 - 1 = 1 。
第二个子序列中最大值和最小值的差值是 3 - 3 = 0 。
由于创建了两个子序列,返回 2 。注意,另一种最优解法是将 nums 划分成子序列 [1] 和 [2,3] 。

示例 3:

输入:nums = [2,2,4,5], k = 0
输出:3
解释:
可以将 nums 划分为三个子序列 [2,2]、[4] 和 [5] 。
第一个子序列中最大值和最小值的差值是 2 - 2 = 0 。
第二个子序列中最大值和最小值的差值是 4 - 4 = 0 。
第三个子序列中最大值和最小值的差值是 5 - 5 = 0 。
由于创建了三个子序列,返回 3 。可以证明需要划分的最少子序列数目就是 3 。

提示:

  • 1 <= nums.length <= 10^5
  • 0 <= nums[i] <= 10^5
  • 0 <= k <= 10^5

解题

方法一:模拟 排序

思路

那么对于升序数组中的每个索引 i,就有子序列 {nums[i],nums[j]}(nums[j]nums[i]+k)\{nums[i], nums[j]\}(nums[j] \leq nums[i] + k) 是一个以 nums[i] 为起始最大合法序列,遍历寻找这样子序列,每找到一个就把计数自增。

具体做法是:先把数组升序,然后初始化第一个序列中最小的的元素(min)为 nums[0] ,从 i=1 开始枚举数组中的元素,如果当前元素比当前序列中的最大可能元素(min+k)要大,那么就需要新分一个子序列了,把子序列计数自增,然后把 min 置为新子序列的最小值(也就是当前枚举到的元素),最后返回计数(ans)即可。

代码

class Solution {
    public int partitionArray(int[] nums, int k) {
        Arrays.sort(nums);
        int ans = 1;
        int min = nums[0];
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > min + k) {
                ans++;
                min = nums[i];
            }
        }
        return ans;
    }
}
0

评论区