アルゴリズム(5):逆序数を見つける

面接の質問から始めましょう

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;
}

演算結果:

おすすめ

転載: blog.csdn.net/weixin_40179091/article/details/111936175