Minimize Deviation in Array (H)
题目
You are given an array nums
of n
positive integers.
You can perform two types of operations on any element of the array any number of times:
- If the element is even, divide it by 2.
- For example, if the array is
[1,2,3,4]
, then you can do this operation on the last element, and the array will be[1,2,3,2].
- For example, if the array is
- If the element is odd, multiply it by 2.
- For example, if the array is
[1,2,3,4]
, then you can do this operation on the first element, and the array will be[2,2,3,4].
- For example, if the array is
The deviation of the array is the maximum difference between any two elements in the array.
Return the minimum deviation the array can have after performing some number of operations.
Example 1:
Input: nums = [1,2,3,4]
Output: 1
Explanation: You can transform the array to [1,2,3,2], then to [2,2,3,2], then the deviation will be 3 - 2 = 1.
Example 2:
Input: nums = [4,1,5,20,3]
Output: 3
Explanation: You can transform the array after two operations to [4,2,5,5,3], then the deviation will be 5 - 2 = 3.
Example 3:
Input: nums = [2,10,8]
Output: 3
Constraints:
n == nums.length
2 <= n <= 10^5
1 <= nums[i] <= 10^9
题意
对一个数组中的数可以进行两种操作:偶数除以2,奇数乘以2。问经过一系列操作,能得到的数组最大值和最小值差值的最小值。
思路
为了统一操作,可以先把数组中所有奇数乘以2,这样只需要考虑除以2的操作,得到的新数组和旧数组是等价的。记录最小值,将所有数加入优先队列中,每次取出最大的数top,减去最小值并更新最小差值,如果top是偶数,则除以2重新加入优先队列,否则跳出循环。
代码实现
Java
class Solution {
public int minimumDeviation(int[] nums) {
int ans = Integer.MAX_VALUE;
int min = Integer.MAX_VALUE;
Queue<Integer> q = new PriorityQueue<>((a, b) -> b - a);
for (int num : nums) {
num = num % 2 == 1 ? num * 2 : num;
q.offer(num);
min = Math.min(min, num);
}
while (true) {
int max = q.poll();
ans = Math.min(ans, max - min);
if (max % 2 == 1) {
break;
}
max /= 2;
min = Math.min(min, max);
q.offer(max);
}
return ans;
}
}