2024.4.8力扣每日一题——使数组连续的最少操作数

题目来源

力扣每日一题;题序:2009

我的题解

方法一 去重+排序+滑动窗口

参考官方题解
记数组 nums的长度为 n。经过若干次操作后,若数组变为连续的,那么数组的长度不会改变,仍然为 n,且数组最大值与最小值之差为 n−1,所有元素均不相同。可以反向考虑,假设最后连续的数组的最小值为 left,则最大值 right=left+n−1。原数组 nums 中,如果有位于 [left,right]中的,如果只出现一次,可以对其进行保留;多次出现时,则需要对其进行操作;不在这个区间的数字,也需要对其进行操作,将它们变成其他数字来对这个区间进行补足。因此,需要统计原数组 nums中,位于区间 [left,right]内不同的数字个数 k,而 n−k 就是需要进行的操作数。
接下来就是需要确定 left,可以将原数组 nums 所有不同的数字作为 left的候选值,分别计算出 n−k,然后求出最小值。这样的话,可以先将原数字进行去重后排序,然后利用滑动窗口。滑动窗口左端点的值作为 left,然后向右扩展右端点,窗口的长度即为 k,求出所有可能性下最小的 n−k 即可。

时间复杂度:O(n×logn),其中 n 是数组 nums 的长度。排序消耗 O(n×log⁡n),滑动窗口消耗 O(n)。
空间复杂度:O(n)

public int minOperations(int[] nums) {
    Set<Integer> set=new HashSet<>();
    int n=nums.length;
    for(int i=0;i<n;i++){
        set.add(nums[i]);
    }
    List<Integer> list=new ArrayList<>(set);
    list.sort((a,b)->a-b);
    int count=0;
    int res=n;
    for(int i=0;i<list.size();i++){
        int left=list.get(i);
        int right=left+n-1;
        //移动窗口
        while(count<list.size()&&list.get(count)<=right){
            res=Math.min(res,n-(count-i+1));
            count++;
        }
    }
    return res;
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜的小彭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值