JZ35 劍指offer 陣列中的逆序對

2021-10-17 03:22:27 字數 2976 閱讀 3427

題目描述

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數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對。分治思想,採用歸併排序的思路來處理。在合併兩個有序序列時,同時計算逆序對數。對...