別具一格 讓所有數字都相異的最少加法操作 Min Increment Make Array Unique_LC#945

更新於 發佈於 閱讀時間約 4 分鐘

題目敘述 Minimum Increment to Make Array Unique

給定一個整數陣列,每回合可以任意挑一個數字進行+1的加法操作。
請問最少需要多少次的+1加法操作,才能讓每個數字都相異?


測試範例

Example 1:

Input: nums = [1,2,2]
Output: 1
Explanation: After 1 move, the array could be [1, 2, 3].

2 調整成 3
需要一次加法操作。​

Example 2:

Input: nums = [3,2,1,2,1,7]
Output: 6
Explanation: After 6 moves, the array could be [3, 4, 1, 2, 5, 7].
It can be shown with 5 or less moves that it is impossible for the array to have all unique values.

1 調整成 2
第一個2 調整成 3
第二個2 調整成 4
3 調整成 5

總共需要六次加法操作。​

約束條件

Constraints:

  • 1 <= nums.length <= 10^5

陣列長度介於1~十萬。

  • 0 <= nums[i] <= 10^5

每個陣列元素介於1~十萬。


觀察

每個整數都要相異,相當於把重複的整數重新mapping到更大的整數
而且為了讓加法操作數目越少越好,重新mapping的距離越近越好,也就是離自己越近越好


這個過程就相當於hash function中的線性探測linear probing,遇到碰撞時,
重新往右側尋找空的格子,每次往右找一格,一直找到空格子為止


演算法 線性探測

維護一張hash table,儲存每個整數對應到的格子點。

最理想的情況是 x -> x,映射到原本的位置,這樣就不需要額外加法。

假如遇到碰撞時,也就是重複的整數,往右側尋找空的格子,找到之後,把原本重複的x映射到右側離自己最近的整數,並且計算對應的+1加法操作次數。


程式碼 線性探測

class Solution(object):
def minIncrementForUnique(self, nums):

# Linear probing to find vacant index in grid
def findVacant(number, grid):

vacantIndex = grid[number]
if vacantIndex == -1:
grid[number] = number
return number

vacantIndex = findVacant(vacantIndex + 1, grid)
grid[number] = vacantIndex
return vacantIndex
# ------------------------------------------------

# index: integer
# value: index of vacant grid
grid = defaultdict(lambda :-1)
incOperation = 0
for number in nums:
vacantIndex = findVacant(number, grid)
incOperation += vacantIndex - number

return incOperation

複雜度分析

時間複雜度:O(n)

線性掃描每個整數,每個整數可以在常數時間內找到空的格子。


空間複雜度: O(n)

需要一個Hash table來儲存每個整數被映射到的格子點。


關鍵知識點

每個整數都要相異,相當於把重複的整數重新mapping到更大的整數

而且為了讓加法操作數目越少越好,重新mapping的距離越近越好,也就是離自己越近越好


這個過程就相當於hash function中的線性探測linear probing,遇到碰撞時,

重新往右側尋找空的格子,每次往右找一格,一直找到空格子為止


Reference

[1] Minimum Increment to Make Array Unique - LeetCode

avatar-img
93會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言4
avatar-img
留言分享你的想法!

































































Paint House 題目會給定一個成本陣列costs,分別代表每棟房屋粉刷成紅色、藍色、綠色的成本。 請問粉刷所有房屋的最小成本是多少,而且相鄰的房屋不可同一種顏色。
題目敘述 Longest Arithmetic Subsequence of Given Difference 給定一個整數陣列nums,請找出給定公差difference的最長的等差數列的長度是多少?
題目敘述 Solving Questions With Brainpower 給定一個測驗題陣列,每個欄位都是一個pair, 分別記錄測驗題做完可以得到的分數,和需要的冷卻時間 (也就是會有一段時間不能作答接下來的題目)。 請問在最佳的答題策略下,最多可以獲得多少分數?
題目敘述 Sort Colors 給定一個色彩陣列,裡面的顏色包含0紅色,1白色,2藍色。 要求我們透過in-place操作,把色彩陣列依序從左到右排好, 依序出現的是紅色、白色、藍色。
題目敘述 Binary Tree Maximum Path Sum 給定一個二元樹,請找出最大的區間路徑和是多少? 註: 區間路徑和 = 某個節點a -> 某個節點b的路徑節點值總和。
題目敘述 Combination Sum IV 給定一個輸入陣列nums,和目標值target,從nums裡面挑數字去湊出總和 = target,數字可以重複挑選。 請問有多少排列數可以湊出target? 註: 排列數的意思就是位置不同代表兩種不同的方法數。
Paint House 題目會給定一個成本陣列costs,分別代表每棟房屋粉刷成紅色、藍色、綠色的成本。 請問粉刷所有房屋的最小成本是多少,而且相鄰的房屋不可同一種顏色。
題目敘述 Longest Arithmetic Subsequence of Given Difference 給定一個整數陣列nums,請找出給定公差difference的最長的等差數列的長度是多少?
題目敘述 Solving Questions With Brainpower 給定一個測驗題陣列,每個欄位都是一個pair, 分別記錄測驗題做完可以得到的分數,和需要的冷卻時間 (也就是會有一段時間不能作答接下來的題目)。 請問在最佳的答題策略下,最多可以獲得多少分數?
題目敘述 Sort Colors 給定一個色彩陣列,裡面的顏色包含0紅色,1白色,2藍色。 要求我們透過in-place操作,把色彩陣列依序從左到右排好, 依序出現的是紅色、白色、藍色。
題目敘述 Binary Tree Maximum Path Sum 給定一個二元樹,請找出最大的區間路徑和是多少? 註: 區間路徑和 = 某個節點a -> 某個節點b的路徑節點值總和。
題目敘述 Combination Sum IV 給定一個輸入陣列nums,和目標值target,從nums裡面挑數字去湊出總和 = target,數字可以重複挑選。 請問有多少排列數可以湊出target? 註: 排列數的意思就是位置不同代表兩種不同的方法數。
你可能也想看
Google News 追蹤
Thumbnail
接續著上次提到的 COUNT、COUNTA,我們再稍稍延伸一點,把 COUNT 函式的家族補完,介紹最後的兩名成員:COUNTUNIQUE 跟 COUNTBLANK。
Thumbnail
接續著上次提到的 COUNT、COUNTA,我們再稍稍延伸一點,把 COUNT 函式的家族補完,介紹最後的兩名成員:COUNTUNIQUE 跟 COUNTBLANK。