LeetCode 周赛217D 5616. 数组的最小偏移量 (有序集合 + 优先队列)

博客介绍了LeetCode周赛中的一道题目——5616.数组的最小偏移量。文章通过Java代码解释了如何利用优先队列动态维护数组中的最大值,从而逐步减小偏移量。关键步骤包括将数组元素转换为可变化范围的最大值,然后不断缩小最大值,直至找到最小偏移量。整个过程的时间复杂度为O(NlogN),空间复杂度为O(N)。
摘要由CSDN通过智能技术生成

LeetCode周赛217D:5616. 数组的最小偏移量

在这里插入图片描述


概述: 把所有数都变成自己可变化范围的最大值, 然后不断缩小当前的最大值.

首先: 一个数的变化范围有限, 比如所有的奇数都只能做一次乘 2 操作, 偶数可以做若干次除以 2 的操作.

比如 3 可以变成 3, 6; 4 可以变成 1, 2, 4; 12 可以变成 3, 6, 12…

数值可以双向变化不好处理, 我们先变成单向的: 把所有数都变成自己可变化范围的最大值.

那么现在剩下的操作就只有把数缩小了.

而偏移量 = 最大值 - 最小值, 所以我们要做的就是缩小最大值. (缩小其他数值也无法优化偏移量)

那么操作就是: 不断缩小当前的最大值即可, 直到不能缩小, 期间不断维护答案.

Java 使用 T r e e S e t TreeSet TreeSet 或者 P r i o r i t y Q u e u e PriorityQueue PriorityQueue 都可以动态维护最大值.

空间复杂度 O ( N ) O(N) O(N), 时间复杂度 O ( N l o g N l o g N ) O(NlogNlogN) O(NlogNlogN)

最多循环 N l o g N NlogN NlogN 次, 因为一个数除以 2 的次数是 l o g N logN logN; 每次循环是 l o g N logN logN.



优先队列


class Solution {
    public int minimumDeviation(int[] nums) {
        TreeSet<Integer> set = new TreeSet<>();
        int ans = Integer.MAX_VALUE;
        int len = nums.length;
        
        for(int i = 0; i < len ; i++){
            set.add((nums[i] % 2) == 0 ? nums[i] : nums[i] * 2);
        }

        // 直到奇数停下
        // ans > 0 && 
        while(set.last() % 2 == 0){
            int mx = set.last();
            set.remove(mx);
            set.add(mx / 2);
            ans = Math.min(ans, set.last() - set.first());
        }

        return ans;
    }
}






作者:MMMMMModddl 题解: 有序集合/优先队列 循环处理Sky

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值