面接の質問から始めましょう
2010年のマイクロソフトのインタビューの質問:
配置では、数字のペアの前後の位置が反対の大きさの順序である場合、つまり、前の数字が後ろの数字よりも大きい場合、それらは逆序数ペアと呼ばれます。
アレンジメントの逆数の総数は、アレンジメントの逆数と呼ばれます。たとえば、{2,4,3,1}では、2と1、4と3、4と1、3と1は、逆序数のペアです。
したがって、配列全体の逆順序ペアの数は4です。配列が与えられた場合、配列内の逆順序ペアの数を数える必要があります。
解決策:逆順序数の数が表示されたときに、一般的なマージソートについて考えたことはありますか?この記事の逆順序数の解決策は、マージソートから派生した方法です。
たとえば、2つの連続したシーケンスがあります。
arr1 [] = {1,3,5}
arr2 [] = {2,2}
シーケンスビットで構成:1、3、5、2、2
arr1 [i] <arr2 [j]の場合、逆順かどうかはわかりません。
ただし、arr1 [i]> arr2 [j]の場合、この時点で逆ペアが形成されます。
アルゴリズムの実装で見逃せないもう1つのポイントがあります。たとえば、arr2は小さいためマージソートにマージされ、arr1には残りの要素が含まれ、残りの要素と元のarrの各要素は逆になります。注文ペア。
/*================================================================
* Copyright (C) 2020 baichao All rights reserved.
*
* 文件名称:mergeSort.cpp
* 创 建 者:baichao
* 创建日期:2020年12月28日
* 描 述:
*
================================================================*/
#include <iostream>
int inverNumCount = 0;
int sort(int *arr,int *temp,int start,int end)
{
if(start >= end)
return -1;
int k = start,len;
int start1,end1,start2,end2;
int mid = start + (end-start)/2;
sort(arr,temp,start,mid);
sort(arr,temp,mid+1,end);
start1 = start;
end1 = mid;
start2 = mid +1;
end2 = end;
int flag = 0;
while(start1 <= end1 || start2 <= end2)
{
if(start2>end2)
{
inverNumCount += (end-mid);
flag = 1;
temp[k++] = arr[start1++];
continue;
}
if(start1 > end1)
{
temp[k++] = arr[start2++];
continue;
}
if(arr[start1] <= arr[start2])
{
temp[k++] = arr[start1++];
}
else
{
temp[k++] = arr[start2++];
inverNumCount++;
}
}
for(int i = start; i <= end; ++i)
arr[i] = temp[i];
if(flag ==1)
inverNumCount -= (end-mid);
}
int mergeSort(int *arr,int arr_size)
{
int temp[arr_size];
sort(arr,temp,0,arr_size - 1);
std::cout<<inverNumCount<<std::endl;
return 0;
}
int main()
{
int arr[] = {1,3,5,2,2};
mergeSort(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}
演算結果: