offer46的題意要求是:先定義在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。然後input乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果output, 即輸出p%1000000007。
對時間複雜度不作要求時,順序掃瞄整個陣列,每掃瞄到乙個數字的時候,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這兩個數字就組成乙個逆序對。這樣時間複雜度是o(n
2)o(n^2)
o(n2
)
# offer46-solution 1
definversepairs
(self, data):if
len(data)
<=1:
return
0 count =
0 length =
len(data)
for i in
range
(length -1)
:for j in
range
(i +
1, length)
:if data[i]
> data[j]
: count +=
1return count %
1000000007
在暴力法的基礎上進行sort及時排序和一些優化,可以讓時間複雜度降低至o(n
logn
)o(nlogn)
o(nlog
n)
# offer46-solution 2
definversepairs
(self, data):if
len(data)
<=0:
return
0 count =
0 copy =
# 預處理
for i in
range
(len
(data)):
)# 對於每乙個data,先加進copy陣列中
copy.sort(
)# 然後立刻排序
i =0while
len(copy)
> i:
count += data.index(copy[i]
)# 由於輸入的數不相同,對於每乙個數,count+
data.remove(copy[i]
) i +=
1return count %
1000000007
關於歸併排序,其實我一開始也沒想到,而且自己寫**也寫得奇奇怪怪,請參考下面的鏈結的解說。以下是我照貓畫虎寫的**。
劍指offer(三十五):陣列中的逆序對
:# 歸併排序法
definversepairs
(self, data):if
len(data)
<=0:
return
0 length =
len(data)
copy =[0
]* length
for i in
range
(length)
: copy[i]
= data[i]
# copy陣列為原陣列data的複製,在後面充當輔助陣列
count = self.core(data, copy,
0, length -1)
return count %
1000000007
defcore
(self, data, copy, start, end)
:if start == end:
copy[start]
= data[start]
return
0 length =
(end - start)//2
# length為劃分後子陣列的長度
left = self.core(copy, data, start, start + length)
right = self.core(copy, data, start + length +
1, end)
# 初始化i為前半段最後乙個數字的下標
i = start + length
# 初始化j為後半段最後乙個數字的下標
j = end
# indexcopy為輔助陣列的指標,初始化其指向最後一位
indexcopy = end
# 準備開始計數
count =
0# 對兩個陣列進行對比取值的操作:
while i >= start and j >= start + length +1:
if data[i]
> data[j]
: copy[indexcopy]
= data[i]
indexcopy -=
1 i -=
1 count += j - start - length
else
: copy[indexcopy]
= data[j]
indexcopy -=
1 j -=
1while i >= start:
copy[indexcopy]
= data[i]
indexcopy -=
1 i -=
1while j >= start + length +1:
copy[indexcopy]
= data[j]
indexcopy -=
1 j -=
1return count + left + right
劍指offer全套解答 劍指offer 46 55
46.孩子們的遊戲 圓圈中最後剩下的數 每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。hf作為牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的 首先,讓小朋友們圍成乙個大圈。然後,他隨機指定乙個數m,讓編號為0的小朋友開始報數。每次喊到m 1的那個小朋友要出...
劍指offer46 乘積陣列的構建
例如 a 求b b 0 a 1 a 2 a 3 2 3 4 24 b 1 a 2 a 3 a 0 3 4 1 12 b 2 a 3 a 0 a 1 4 1 2 8 b 3 a 0 a 1 a 2 1 2 3 6 三 思想 1 遍歷陣列a,沒遍歷一次就在陣列b中增加乙個對應的元素 2 陣列b中要寫入是...
劍指offer 46 撲克牌順子
ll今天心情特別好,因為他去買了一副撲克牌,發現裡面居然有2個大王,2個小王 一副牌原本是54張 他隨機從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿!紅心a,黑桃3,小王,大王,方片5 oh my god 不是順子 ll不高興了,他想了想,決定大 小...