給定乙個陣列nums
,如果i < j
且nums[i] > 2*nums[j]
我們就將(i, j)
稱作乙個重要翻轉對。
你需要返回給定陣列中的重要翻轉對的數量。
示例:
輸入: [1,3,2,3,1]
輸出: 2
注意:
給定陣列的長度不會超過50000
。
輸入陣列中的所有數字都在32位整數的表示範圍內
歸併排序可以解決此題,也可以採用樹狀陣列 + 離散化來解決此題。
樹狀陣列之前考研複試複習時隨便看了兩遍,但當時並沒有理解,也沒用強行記下來。在做這題的時候,csl同學又給我講了一遍樹狀陣列,有那麼一點點的感覺,因此記下。
首先是樹狀陣列。浙大《演算法筆記》中介紹的比較詳細。
對於此題,就是將該陣列的值域開乙個樹狀陣列 min(nums) 到 max(nums) * 2 。這裡將其離散化。不然陣列太大。
接著遍歷nums ,算出樹狀陣列小於等於當前值的兩倍的個數,再用當前樹狀陣列的總的個數減去它,即是之前的值大於當前值兩倍的個數。
接著更新樹狀陣列。
class solution:
def reversepairs(self, nums) -> int:
tmp = list(set(nums + [2 * x for x in nums])) # 去重
tmp.sort() # 排序
tot = len(tmp)
v = # 離散化
tr = [0] * (tot + 1) # 開樹狀陣列
def get(x):
i = x
res = 0
while i > 0:
res += tr[i]
i -= i & -i
return res
def add(x,c):
i = x
while i <= tot:
tr[i] += c
i += i & -i
n = len(nums)
res = 0
for j in range(n):
res += get(tot) - get(v[nums[j] * 2]) # 統計個數
add(v[nums[j]],1) # 更新樹狀陣列
return res
LeetCode 493 翻轉對 歸併排序
如果 i j 分別屬於兩個有序區間,並且 nums i 2 nums j 則大於 i 的元素也都滿足需求,利用有序特點可以減少重複的比較操作。將兩個有序的陣列合併成乙個有序陣列稱為歸併。歸併排序包含了兩個過程 從上往下的分解 把當前區間一分為二,直至分解為若干個長度為1的子陣列 從下往上的合併 兩個...
leetcode493(翻轉對 歸併排序)
給定乙個陣列 nums 如果 i j 且 nums i 2 nums j 我們就將 i,j 稱作乙個重要翻轉對。你需要返回給定陣列中的重要翻轉對的數量。示例 1 輸入 1,3,2,3,1 輸出 2 示例 2 輸入 2,4,3,5,1 輸出 3 題解 一 歸併排序,在歸併排序的過程中,假設對於某歸併陣...
《leetcode》189 旋轉陣列《翻轉陣列》
難度中等848 給定乙個陣列,將陣列中的元素向右移動k個位置,其中k是非負數。高階 示例 1 輸入 nums 1,2,3,4,5,6,7 k 3輸出 5,6,7,1,2,3,4 解釋 向右旋轉 1 步 7,1,2,3,4,5,6 向右旋轉 2 步 6,7,1,2,3,4,5 向右旋轉 3 步 5,6...