Algorithm (5): Find the inverse ordinal number

Let's start with an interview question

Microsoft interview questions in 2010:

In an arrangement, if the front and back positions of a pair of numbers are in the opposite order of magnitude, that is, the number in the front is greater than the number in the back, then they are called an inverse ordinal number pair.

The total number of inverse orders in an arrangement is called the inverse number of the arrangement. For example, in {2, 4, 3, 1}, 2 and 1, 4 and 3, 4 and 1, 3 and 1 are pairs of inverse ordinal numbers,

Therefore, the number of inverse ordinal pairs of the entire array is 4. Now given an array, it is required to count the number of inverse ordinal pairs in the array.

 

Solution: Have you ever thought of our common merge sort when you see the number of inverse ordinal numbers ? The solution to the inverse ordinal number in this article is a method derived from merge sort.

For example, we now have two sequential sequences:

arr1 [] = {1,3,5}

arr2[] = {2,2}

Consisting of sequence bits: 1,3,5,2,2

When arr1[i] <arr2[j], it cannot be seen whether there is a reverse order

But when arr1[i]> arr2[j], then a reverse pair is formed at this time;

There is one point that cannot be missed when the algorithm is implemented. For example, if arr2 is merged in the merge sort because it is smaller, there will be remaining elements in arr1, and the remaining elements and each element of the original arr constitute a reverse order pair.

/*================================================================
 *   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;
}

operation result:

Guess you like

Origin blog.csdn.net/weixin_40179091/article/details/111936175