Leetcode 945 使陣列唯一的最小增量

2021-10-08 20:16:59 字數 2844 閱讀 2527

給定整數陣列 a,每次 move 操作將會選擇任意 a[i],並將其遞增 1。

返回使 a 中的每個值都是唯一的最少操作次數。

示例 1:

輸入:[1,2,2]

輸出:1

解釋:經過一次 move 操作,陣列將變為 [1, 2, 3]。

示例 2:

輸入:[3,2,1,2,1,7]

輸出:6

解釋:經過 6 次 move 操作,陣列將變為 [3, 4, 1, 2, 5, 7]。

可以看出 5 次或 5 次以下的 move 操作是不能讓陣列的每個值唯一的。

我們先把陣列從小到大排序,排序後進行一次遍歷,將遍歷過程中重複的元素儲存到乙個list-a中,並且將沒有出現的數字(比如[2,4],3沒有出現,儲存3)儲存到另乙個list-b中。

那麼下一步分別設立兩個指標ij,從ab的頭部開始向後遍歷,如果a[i] < b[j],則說明對於a[i]需要移動b[j] - a[i]次才可以滿足要求。

當b遍歷完而a還沒遍歷完時,說明a中剩餘的元素只能移動到原陣列最末端才可以,此時我們相當於將j指標指到原陣列的末端後一位,繼續遍歷直到結束。

**如下:

class

solution

:def

minincrementforunique

(self, a: list[

int])-

>

int:

ifnot a:

return

0 a.sort(

) cand =

pos =

res =

0for i in

range(0

,len

(a)-1)

:#儲存重複元素

if a[i]

== a[i +1]

:)elif a[i +1]

- a[i]

>1:

#儲存未出現數字

pos +=

[_ for _ in

range

(a[i]+1

, a[i +1]

)]i = j =

0#遍歷兩陣列

while i <

len(cand)

and j <

len(pos)

:if cand[i]

< pos[j]

: res += pos[j]

- cand[i]

i +=

1 j +=

1else

: j +=

1 r_pos = a[-1

]+1#重複元素陣列未遍歷完 從原陣列末端繼續遍歷

while

(i <

len(cand)):

res += r_pos - cand[i]

i +=

1 r_pos +=

1return res

排序時間複雜度為o(n

logn

)o(nlogn)

o(nlog

n),因此總的時間複雜度為o(n

logn

)o(nlogn)

o(nlog

n)。在排序之後,相同的多個元素將會是連續的,而且元素是由小變大的。在這裡我們設定兩個變數:taken和ans。taken用來表示重複的並且還沒有move的元素,ans則用來表示移動的次數。那麼當我們碰到相同元素時,taken++,ans應該怎麼變化呢。注意到 ans += (找到的位置 - 重複的元素), 因此我們可以先減去重複的元素,並且由於陣列是遞增的,我們只需要在之後的搜尋過程中找到位置即可。所以哦鞥到相同元素時,ans -= 重複元素。

下一步我們需要考慮如何找位置以及找到位置之後的操作。那麼當對於排序之後的陣列,當a[i] < a[i+1]時,並且當taken不為空時,a[i] 和a[i+1]之間的元素便是之前的重複元素可以移動的位置。當移動到陣列末端並且taken不為空時,陣列末端元素便是移動的位置了。

**如下:

class

solution

:def

minincrementforunique

(self, a: list[

int])-

>

int:

a.sort(

)100000

)##設定右邊界,主要為了在到達末端時符合下面的判斷條件

ans = taken =

0for i in

range(1

,len

(a))

:if a[i-1]

== a[i]

: taken +=

1 ans -= a[i]

else

: give =

min(taken, a[i]

- a[i-1]

-1)##二者取最小,表示可以移動的位置

ans += give *

(give +1)

//2+ give * a[i-1]

taken -= give

return ans

時間複雜度為o(n

logn

)o(nlogn)

o(nlogn)。

Leetcode 945 使陣列唯一的最小增量

給定整數陣列 a,每次 move 操作將會選擇任意a i 並將其遞增1。返回使a中的每個值都是唯一的最少操作次數。示例 1 輸入 1,2,2 輸出 1解釋 經過一次 move 操作,陣列將變為 1,2,3 示例 2 輸入 3,2,1,2,1,7 輸出 6解釋 經過 6 次 move 操作,陣列將變為...

leetcode945 使陣列唯一的最小增量

給定整數陣列 a,每次 move 操作將會選擇任意 a i 並將其遞增 1。返回使 a 中的每個值都是唯一的最少操作次數。示例 1 輸入 1,2,2 輸出 1 解釋 經過一次 move 操作,陣列將變為 1,2,3 示例 2 輸入 3,2,1,2,1,7 輸出 6 解釋 經過 6 次 move 操作...

LeetCode 945 使陣列唯一的最小增量

給定整數陣列 a,每次 move 操作將會選擇任意 a i 並將其遞增 1。返回使 a 中的每個值都是唯一的最少操作次數。示例 1 輸入 1,2,2 輸出 1 解釋 經過一次 move 操作,陣列將變為 1,2,3 示例 2 0 a.length 40000 0 a i 40000 我是用雜湊表做的...