1. 程式人生 > 其它 >[LeetCode] 1675. Minimize Deviation in Array

[LeetCode] 1675. Minimize Deviation in Array

You are given an arraynumsofnpositive integers.

You can perform two types of operations on any element of the array any number of times:

  • If the element iseven,divideit by2.
    • 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].
  • If the element isodd,multiplyit by2
    .
    • 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].

Thedeviationof the array is themaximum differencebetween any two elements in the array.

Returntheminimum deviationthe 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 <= 105
  • 1 <= nums[i] <= 109

陣列的最小偏移量。

給你一個由 n 個正整陣列成的陣列 nums 。

你可以對陣列的任意元素執行任意次數的兩類操作:

如果元素是 偶數 ,除以 2
例如,如果陣列是 [1,2,3,4] ,那麼你可以對最後一個元素執行此操作,使其變成 [1,2,3,2]
如果元素是 奇數 ,乘上 2
例如,如果陣列是 [1,2,3,4] ,那麼你可以對第一個元素執行此操作,使其變成 [2,2,3,4]
陣列的 偏移量 是陣列中任意兩個元素之間的 最大差值 。

返回陣列在執行某些操作之後可以擁有的 最小偏移量 。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/minimize-deviation-in-array
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

這算是一道貪心的題目吧,思路不好想。

這道題有幾個地方需要注意,首先,題目對於偏移量的定義其實是陣列中最大的元素 - 最小的元素,我們的最終目的是要使得這個偏移量儘可能的小。同時注意題目允許的操作只有對偶數做除法和對奇數做乘法,所以如果想使得偏移量儘可能的小,我們應該讓最大值儘可能地小,直到最大值是一個奇數為止,因為奇數是不能再做除法的。這裡我們對 input 陣列中的最小值不做任何變動,因為如果這個最小值是奇數的話,我們的確可以乘以 2,但是當我們下一輪再次掃描的時候,這個偶數又會被除以 2 變成奇數,這就是一個死迴圈了。所以大體思路是儘量把大的數字通過除以2的方式變小,來找最終那個最小的偏移量。

具體做法是首先將 input 陣列中所有奇數乘以2,變成偶數,同時把所有數字都放入一個類似堆的資料結構裡,這樣可以做到自動排序。我這裡的程式碼實現用的是 treeset。用treeset 的原因是因為無需考慮重複的元素,只要能將所有 unique 的元素做到有序,方便我拿到最大的和最小的元素即可。將所有元素放入treeset 之後,我去看一下treeset 中的最大元素,如果他是偶數,那麼我把他除以 2 再放回treeset,如此迴圈往復直到treeset 中最大的元素是奇數為止。此時treeset 中最大元素 - 最小元素的差即是題目要找的最小的偏移量。

這道題的時間複雜度如下,因為陣列中最大的數字有可能是 2 的倍數,所以對這個數字不斷除以 2 的最大花費會到 logM,同時陣列內可能所有元素都是偶數所以可能每個元素都需要做如此多的除以 2 的操作。如果陣列的長度用 N 來表示的話,這一塊的時間複雜度是O(NlogM)。同時又因為每個元素在除以 2 之後會導致 treeset 的自動排序,所以又要乘以 logN。總體的複雜度是O(NlogM * logN)

時間 O(NlogM * logN)

空間 O(n)

Java實現

 1 class Solution {
 2     public int minimumDeviation(int[] nums) {
 3         TreeSet<Integer> set = new TreeSet<>();
 4         for (int num : nums) {
 5             if (num % 2 == 1) {
 6                 set.add(num * 2);
 7             } else {
 8                 set.add(num);
 9             }
10         }
11 
12         int res = Integer.MAX_VALUE;
13         while (true) {
14             int top = set.last();
15             res = Math.min(res, top - set.first());
16             if (top % 2 == 0) {
17                 set.remove(top);
18                 set.add(top / 2);
19             } else {
20                 break;
21             }
22         }
23         return res;
24     }
25 }

LeetCode 題目總結