陣列中的逆序對

2021-09-26 07:12:34 字數 3324 閱讀 2758

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。 即輸出p%1000000007

題目保證輸入的陣列中沒有的相同的數字

資料範圍:

對於%50的資料,size<=10^4

對於%75的資料,size<=10^5

對於%100的資料,size<=2*10^5

示例1複製

1,2,3,4,5,6,7,0
複製

7
方法一:暴力

# -*- coding:utf-8 -*-

class solution:

def inversepairs(self, data):

# write code here

count=0

n=len(data)

for i in range(n-1):

for j in range(1+i,n):

if data[i]>data[j]:

count+=1

return count

方法二:索引

import copy

def inversepairs(data):

count = 0

copys = copy.copy(data)

# copys=data[:]

# copys = copy.deepcopy(data)

copys.sort()

for i in range(len(copys)):

count += data.index(copys[i])

print('count=',count)

data.remove(copys[i])

return count

# return count%1000000007

a=[1,2,3,5,6,7,4]

print(inversepairs(a))

方法三:歸併

class solution:

def reversepairs(self, nums: list[int]) -> int:

def f(l,r):

if l>=r:

return 0

mid=(l+r)//2

s=f(l,mid)+f(mid+1,r)

i=lj=mid+1

pos=l

res=

while i<=mid and j<=r:

if nums[i]<=nums[j]:

dp[pos]=nums[i]

i+=1

else:

dp[pos]=nums[j]

j+=1

s=s+(mid-i+1)

pos+=1

for k in range(i,mid+1):

dp[pos]=nums[k]

pos+=1

for k in range(j,r+1):

dp[pos]=nums[k]

pos+=1

nums[l:r+1]=dp[l:r+1]

return s

l=len(nums)

dp=[0]*l

return f(0,l-1)

class solution:

def inversepairs(self, data):

# write code here

# 思路:歸併排序。分為兩個部分,尋找兩個部分內部的逆序列,再尋找兩個部分之間交叉的逆序列。

if not data:

return 0

# 由於必須保證有兩個列表,兩個位址,因此不能直接用assist=data

assist = [i for i in data]

return self.merge(data, assist, 0, len(data) - 1) % 1000000007

# 每乙個新的遞迴開始時,都是要大範圍重新排序的,這個範圍會覆蓋所有以前遞迴過的片段,因此data和assist可以互換,因為上一次排好序的列表只在下一次的比較時需要使用,而不需要遞延到下一次的輔助列表中。

def merge(self, data, assist, low, high):

# 判斷終止條件:如果子部分裡面只剩下1個數,此時low=high,不用比較,返回0

if low == high:

assist[low] = data[low] # 由於assist和data互換了,因此如果遞迴到最小單位,要按照上次算出的排序方式排序

return 0

mid = (low + high) / 2

left = self.merge(assist, data, low, mid)

right = self.merge(assist, data, mid + 1, high)

# 開始歸併排序

count = 0

i = mid

j = high

k = high # k為assist列表的索引

# 從後往前進行遍歷,對左子列和右子列中的數進行比較大小

while i >= low and j > mid:

# 如果左子列最後乙個數大於右子列最後乙個數,表示左子列大於右子列所有的數

if data[i] > data[j]:

count += j - mid # count要加上右子列中剩下元素的個數

assist[k] = data[i] # 將最大的數存入輔助列表

i -= 1 # 最大數已被排序,將左子列向前遍歷乙個元素

# 如果左子列最後乙個數小於等於右子列最後乙個數,不構成逆序對

else:

assist[k] = data[j] # 將最大的數存入輔助列表

j -= 1 # 最大數已被排序,將右子列向前遍歷乙個元素

k -= 1

# 上面乙個while中還會剩下最後乙個元素沒有被排序,進入assist

while i >= low:

assist[k] = data[i]

i -= 1

k -= 1

while j > mid:

assist[k] = data[j]

j -= 1

k -= 1

return left + right + count # 返回當前左右子列計算出的逆序對數量,加上左右子列內部的逆序對數量

陣列中逆序對

題目 在陣列中的兩個數字,如果前面的乙個數字大於後面的數字,則這兩個數字為乙個逆序對。輸入乙個陣列,求這個陣列的逆序對個數。例如 給定陣列 則有 5,3 5,1 8,3 8,1 3,1 這5個逆序對。問題分析 我採用兩種方法來解決這個問題 1 考慮到二叉搜尋樹中每個節點x,它的左子樹所有關鍵字的值小...

陣列中的逆序對

來自劍指offer 分析 我們第一反應是順序掃瞄整個陣列,每掃瞄到乙個數字時,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這個兩個數字就組成了乙個逆序對。假設陣列有n個數字,由於每個數字都要和o n 個數字作比較,因此這個演算法的時間複雜度為o n 2 換思路 我們採用歸併思想,先考...

陣列中的逆序對

題目 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。用歸併排序演算法,歸併的時候,從後向前歸併。include using namespace std int getreversenum int p1,int p2,int...