給定整數陣列 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
中。
那麼下一步分別設立兩個指標i
和j
,從a
和b
的頭部開始向後遍歷,如果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 我是用雜湊表做的...