1. 程式人生 > 其它 >演算法(5):求逆序數

演算法(5):求逆序數

技術標籤:演算法排序演算法演算法

我們從一道面試題入手開始

微軟面試題2010年:

在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為一個逆序數對。

一個排列中逆序的總數就稱為這個排列的逆序數。如{2,4,3,1}中,2和1,4和3,4和1,3和1是逆序數對,

因此整個陣列的逆序數對個數為4,現在給定一陣列,要求統計出該陣列的逆序數對個數。

解:看到逆序數的次數有沒有想到我們常見的歸併排序呢,逆序數的求解本文的分享就是從歸併排序衍生出來的一種方法。

比如我們現在有兩個順序序列:

arr1[] = {1,3,5}

arr2[] = {2,2}

組成的序列位:1,3,5,2,2

當arr1[i] < arr2[j]時,看不出來是否存在逆序

但是當arr1[i] > arr2[j] ,則此時構成逆序對;

演算法實現時還有個點不能遺漏,比如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;
}

執行結果: