Leetcode 1675. Minimize Deviation in Array 两种做法(带注释)

这篇博客探讨了如何使用Java中的TreeSet和PriorityQueue数据结构来解决找到数组中所有元素经过翻倍操作后的最小偏差问题。两种方法的时间复杂度都是O(N*logM*logN),其中N是数据规模,M是数字大小。TreeSet自动维护最大值和最小值,而PriorityQueue需要手动维护最小值。博客还提到了复习知识点,包括Queue中的插入、删除和查询头部的操作。
摘要由CSDN通过智能技术生成

题目链接

1. 使用TreeSet

class Solution {
    public int minimumDeviation(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        TreeSet<Integer> set = new TreeSet<>();
        // 1. Pre-double all the odd numbers, and numbers only can be smaller.
        for (int num : nums) {
            if (num % 2 == 0) set.add(num);
            else set.add(num * 2);
        }
        int result = set.last() - set.first();
        // 2. When the largest number is odd(can't be smaller), stop iteration.
        while (!set.isEmpty() && set.last() % 2 == 0) {
            int maxNum = set.last();
            set.remove(maxNum);
            set.add(maxNum / 2);
            // update the smallest deviation
            result = Math.min(result, set.last() - set.first());
        }
        return result;
    }
}

好处是可以自动更新最大值last和最小值first,并且作为set,能够自动去掉重复元素(对本题来讲重复元素没有意义)。

使用PriorityQueue

class Solution {
    public int minimumDeviation(int[] nums) {
        PriorityQueue<Integer> queue = new PriorityQueue<>(Collections.reverseOrder());
        int lo = Integer.MAX_VALUE;
        // 1. Pre-double all the odd numbers, 
        // and all numbers can only become smaller(by divided).
        for (int num : nums) {
            int x = num % 2 == 0 ? num : num * 2;
            queue.offer(x);
            lo = Math.min(x, lo);
        }
        int result = queue.peek() - lo;
        // 2. Start from the largest number, compare it to the smallest one.
        // Divide it by 2 and put it back to the queue. Update the deviation.
        // Stop iteration when the largest number is odd(can't be smaller).
        while (!queue.isEmpty() && queue.peek() % 2 == 0) {
            int x = queue.poll() / 2;
            queue.offer(x);
            lo = Math.min(lo, x);
            result = Math.min(result, queue.peek() - lo);
            // Iterator iterator = queue.iterator();
            // while (iterator.hasNext())  System.out.print(iterator.next() + " ");
        
        }
        return result;
    }
}

总体思路一样,最大堆实现,要手动维护最小值lo。

复习知识点:Queue中的重复方法

插入删除查询头部
抛异常add()remove()element()
返回 nulloffer()poll()peek()

分析

两种方法时间复杂度均为O(N * logM * logN)。其中N代表数据规模,M代表数字大小。N个元素进出优先队列需要logN,而进出的次数与数字的大小M相关(每次重新进入时除以2)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值