陣列翻轉 LeetCode 493 翻轉對

2021-10-14 18:48:08 字數 1330 閱讀 6086

給定乙個陣列nums,如果i < jnums[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...