タイトル説明
説明タイトル
番号は図面の前後よりも大きい場合には、アレイ内の2つの数字は、2つの数字は逆対を形成します。配列を入力し、この配列P.逆ペアの総数を見出します P結果モジュロ十億七を出力します。すなわち、Pの%十億七出力
入力説明:
タイトルは、入力配列の同じ数がないことを確認します
データ範囲:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
考え
リンク:https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5?f=discussion
出典:牛オフネットワーク
分析を考える:
私たちの最初の反応は、アレイ全体のシーケンシャルスキャンで、このタイトルを参照してください。各時間は、アレイは、その背後にデジタルの数と大きさを比較することによって、いずれかをスキャンします。後者の数字は、それが逆対の形成に、2つの数値よりも小さい場合。配列は、n桁が含まれているとします。各デジタル及びO(n)は、この数を比較しなければならないので、アルゴリズムの時間複雑度は、O(Nである2)。
我々は逆の統計的分析の例として、配列{7,5,6,4}を有します。それぞれ、それ以外の時間の複雑さはO(N-である、我々はTAとの比較のために、すべてのデジタルバックを得ることはありませんが、デジタルにスキャン2)は、私たちは、隣接する2つの数を比較検討することができます。
(a)は、長さ2の2つのサブアレイにアレイ4の長さは、
2に(B)長さ2のアレイのサブアレイ成都1;
(C)サブアレイ1の長さソーティングと逆のカウント、合わせ;
(D)サブアレイ2の長さは、ソートを合わせ、そして逆にカウント、
図(a)及び(b)に示すように、我々は最初の長さ2の二つのアレイに分解。サブアレイは、2つのサブアレイは、長さ1の2つのサブアレイに分割されています。次に、逆の数の統計が、隣接するサブ配列をマージします。第一のサブ配列の長さに7 {1}、{5}の逆対を形成する5、7よりも大きいので、(7,5)です。また、第2のサブ配列の長さで1 {6}、{4}は、逆の順序(6,4)です。我々は、内部統計アレイ2対の順序を逆に持っているので、順番に、後続の統計統計的プロセスで繰り返さ回避するために、上記の(c)に示す二つのサブ配列をソートする必要があります。
次に、我々は、2つのサブサブアレイ2配列間の統計的長さを逆。図に示すようにサブアレイおよび以下の統計逆の合成方法。
我々は、2つのサブ配列の末端には、2つのポインタを有する第一た、二つの数字を各ポインタを比較します。二番目の配列、逆の数と残りの数字で第二のサブアレイに等しい数の逆の構成、以下に示すように(a)および(c)よりも大きい第一のサブ配列番号の場合は数示しています。最初の番号は、図の(b)に示すように、より少ないまたは逆の順序を構成しない二番目の配列の配列に等しい場合。毎回の比較は、我々はの昇順に補助配列は、(コピーと呼ばれる)ことを確認して、補助配列に番号を前方に戻ってからコピーされた高い数値を考えています。二次配列、ポインタの前方への移動に対応する、比較の次のラウンドに大きいデジタル複写後。
工程:次に、サブアレイへの最初の配列、内部逆サブアレイの数の最初の数、隣接する二つのサブアレイ間に逆の数の統計。統計の逆転時には、我々はまた、配列をソートする必要があります。あなたはソートアルゴリズムに精通している場合、我々は、このプロセスは、実際にマージソートであることを見つけます
JSコード
function InversePairs(data)
{
// write code here
let len = data.length
if (len === 0) return 0
const copy = data.concat([])
let count = InversePairsHelp(data, copy, 0, len-1)
return count%1000000007
function InversePairsHelp(data, copy, start, end){
if (start === end) {
copy[start] = data[start]
return 0
}
let mid = Math.floor((end-start) / 2)
let left = InversePairsHelp(copy, data, start, start+mid)
let right = InversePairsHelp(copy, data, start+mid+1, end)
let i = start+mid
let j = end
let count = 0
let indexCopy = end
while(i >= start && j >= start+mid+1){
if (data[i] > data[j]) {
copy[indexCopy--] = data[i--]
count = count + j - start - mid
}else {
copy[indexCopy--] = data[j--]
}
}
for(;i>=start;i--)
copy[indexCopy--]=data[i]
for(;j>=start+mid+1;j--)
copy[indexCopy--]=data[j]
return left+right+count
}
}