題目描述
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。 即輸出p%1000000007
class
solution
void
sort
(vector<
int>
&data,vector<
int>
& tmp,
int l,
int r,
int&ret)
void
merge
(vector<
int>
&data,vector<
int>
& tmp,
int l,
int mid,
int r,
int& ret)
else
}while
(i<=mid)
while
(j<=r)
k = l,i = l;
while
(k<=r)}}
;
class
solution
:def
reversepairs
(self, nums: list[
int])-
>
int:
self.ret =
0 tmp = nums.copy(
)def
merge
(nums,tmp,l,m,r)
: i, j = l, m +
1 tmp[l: r+1]
= nums[l: r+1]
for k in
range
(l,r+1)
:if i == m +1:
nums[k]
= tmp[j]
j +=
1elif j == r +
1or tmp[i]
<= tmp[j]
: nums[k]
= tmp[i]
i +=
1else
: nums[k]
= tmp[j]
self.ret += m - i +
1 j +=
1def
sort
(nums,tmp,l,r)
:if l >= r:
return
mid =
(l + r)//2
sort(nums,tmp,l,mid)
sort(nums,tmp,mid+
1,r)
merge(nums,tmp,l,mid,r)
sort(nums,tmp,0,
len(nums)-1
)return self.ret
class
solution
:def
reversepairs
(self, nums: list[
int])-
>
int:
defmerge_sort
(l, r)
:# 終止條件
if l >= r:
return
0# 遞迴劃分
m =(l + r)//2
res = merge_sort(l, m)
+ merge_sort(m +
1, r)
# 合併階段
i, j = l, m +
1 tmp[l:r +1]
= nums[l:r +1]
for k in
range
(l, r +1)
:if i == m +1:
nums[k]
= tmp[j]
j +=
1elif j == r +
1or tmp[i]
<= tmp[j]
: nums[k]
= tmp[i]
i +=
1else
: nums[k]
= tmp[j]
j +=
1 res += m - i +
1# 統計逆序對
return res
tmp =[0
]*len(nums)
return merge_sort(0,
len(nums)-1
)
思路:
使用歸併排序思想,歸併排序,就是先將區間二分,然後有序的進行合併。開闢tmp陣列來進行合併操作,首先我們根據左右指標,進行二分後,對左、右區間遞迴進行sort,最後再合併然後退回。
合併操作中我們對兩個區間值作比較有序放入位置(因為歸併操作遞迴進行,每個操作前的兩區間區間內有序,所以依次進行判斷再放入tmp,最後結束後再更改原陣列)
對於本題,我們要尋找逆序對,借助歸併排序時我們會判斷不同區間兩個數之間的大小關係
比如如果兩個區間為[4, 3] 和[1, 2]
那麼逆序數為(4,1),(4,2),(3,1),(3,2),同樣的如果區間變為有序,比如[3,4] 和 [1,2]的結果是一樣的,也就是說對於區間之間的逆序對,區間有序和無序結果是一樣的。
但是如果區間有序會有什麼好處嗎?當然,如果區間有序,比如[3,4] 和 [1,2]
如果3 > 1, 顯然3後面的所有數都是大於1, 這裡為 4 > 1, 所以每次我們遇到後面區間值更小時,可以通過當前前面區間指標位置計數,所以在歸併時那個if中進行ret累加。
JZ50 劍指offer 陣列中重複的數字
題目描述 在乙個長度為n的陣列裡的所有數字都在0到n 1的範圍內。陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中第乙個重複的數字。例如,如果輸入長度為7的陣列,那麼對應的輸出是第乙個重複的數字2。返回描述 如果陣列中有重複的數字,函式返回true,否則返回...
劍指offer35 陣列中的逆序對
題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007 輸入描述 題目保證輸入的陣列中沒有的相同的數字 資料範圍 對於 50的資料,size 1...
劍指Offer(35) 陣列中的逆序對
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007。例如輸入,輸出5對。分治思想,採用歸併排序的思路來處理。在合併兩個有序序列時,同時計算逆序對數。對...