【面试必刷TOP101】面试官:如何寻找数组中的逆序数?

作者: 贤蛋大眼萌,一名很普通但不想普通的程序媛 \color{#FF0000}{贤蛋 大眼萌 ,一名很普通但不想普通的程序媛} 贤蛋大眼萌,一名很普通但不想普通的程序媛

语录: 多一些不为什么的坚持 \color{#0000FF}{多一些不为什么的坚持} 多一些不为什么的坚持

专栏:牛客刷题–斩获offer

眼过千遍不如手锤一遍:推荐一款模拟面试,斩获大厂 o f f e r ,程序员的必备刷题平台 − − 牛客网 \color{#ff7f50}{眼过千遍不如手锤一遍:推荐一款模拟面试,斩获大厂offer,程序员的必备刷题平台--牛客网} 眼过千遍不如手锤一遍:推荐一款模拟面试,斩获大厂offer,程序员的必备刷题平台牛客网

点击开启刷题之旅

文章目录

    • 前言
    • 如何寻找数组中的逆序数
    • 总结

前言

牛客网 \color{#ff7f50}{牛客网} 牛客网 是一个集笔面试系统、题库、课程教育、社群交流、招聘内推于一体的招聘类网站,更是一个专注于程序员的学习和成长的平台。

image-20220917155316636

自学是一个程序员必备的能力,而提高自己的编程能力最好方法就是通过刷题。一次偶然的机会让我发现牛客网这个新大陆,开启自己IT之旅。

这里有个大厂的面试真题,知己知彼百战百胜。

更有在线编程调试功能,提高编程效率。点击开始学习

如何寻找数组中的逆序数

描述(题目中等) 考点:数组

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007

数据范围: 对于 50% 的数据, size\≤10^4
对于 100% 的数据, size≤10^5

数组中所有数字的值满足 0≤val≤10^9

要求:空间复杂度 O(n),时间复杂度 O(nlogn)

输入描述:

题目保证输入的数组中没有的相同的数字

【面试必刷TOP101】面试官:如何寻找数组中的逆序数?_第1张图片

解题思路:

  • step 1: 划分阶段:将待划分区间从中点划分成两部分,两部分进入递归继续划分,直到子数组长度为1.
  • step 2: 排序阶段:使用归并排序递归地处理子序列,同时统计逆序对,因为在归并排序中,我们会依次比较相邻两组子数组各个元素的大小,并累计遇到的逆序情况。而对排好序的两组,右边大于左边时,它大于了左边的所有子序列,基于这个性质我们可以不用每次加1来统计,减少运算次数。
  • step 3: 合并阶段:将排好序的子序列合并,同时累加逆序对。

【面试必刷TOP101】面试官:如何寻找数组中的逆序数?_第2张图片

题解:

// 语言①:C
static unsigned int count = 0;
void merge(int *arr, int lo, int mid, int hi);
void mergeSort(int *arr,int lo, int hi)
{
    if(lo == hi) return;
    int mid = (hi +lo) >> 1;
    mergeSort(arr, lo, mid);
    mergeSort(arr ,mid +1, hi);
    merge(arr,lo, mid, hi);
}
void merge(int *arr,int lo, int mid, int hi)
{
    int *B = (int*)malloc((mid - lo +1) * sizeof(int));
    int i,j,k;
    for(i = lo, j = 0; i <= mid; i++)
    {
        *(B + (j++)) = *(arr + i);
    }
    for(i = 0, k = lo, j = mid + 1;i <= mid - lo;)
    {
        if(*(B + i) > *(arr + j) && j <= hi)
        {
            count = count +(mid - lo - i + 1);
            *(arr + (k ++)) = *(arr + (j ++));
        }
        else
        {
            *(arr + (k ++)) = *(B + (i ++));
        }
        //*(arr + (k ++)) = *(B + i) < *(arr + j) || j > hi ? *(B + (i ++)) : *(arr + (j ++));
    }
    free(B);
    count = count % 1000000007;
}
int InversePairs(int* data, int dataLen ) {
 
    mergeSort(data, 0, dataLen - 1);
    return count;
}
// 语言②:JavaScript
function feng(data,x,y,sum){
    if(x<y){
        let k = parseInt(JSON.stringify((x+y)/2));
        feng(data,x,k,sum);
        feng(data,k+1,y,sum);
        hebing(data,x,k,y,sum);
    }
}
function hebing(data,x,k,y,sum){//中间值k属于左侧
    let i=x,j=k+1,len=0;
    while(i<=k&&j<=y){
        if(data[i]>data[j]){
            ans+=k-i+1;
            sum[len++]=data[j++];
        } else{
            sum[len++]=data[i++];
        }
    }
    while(i<=k){
        sum[len++]=data[i++];
    }
    while(j<=y){
        sum[len++]=data[j++];
    }
    for(let db=x;db<=y;++db){
        data[db]=sum[db-x];
    }
    ans=ans%1000000007;
}
function InversePairs(data)
{
    // write code here
    let sum = [];
    feng(data,0,data.length-1,sum);
    return ans%1000000007;
}
module.exports = {
    InversePairs : InversePairs
};

【面试必刷TOP101】面试官:如何寻找数组中的逆序数?_第3张图片

总结

求知无坦途,学问无捷径。 一步一个脚印,你走过的路,每一步都算数。 \color{#ff7f50}{一步一个脚印,你走过的路,每一步都算数。} 一步一个脚印,你走过的路,每一步都算数。 每一次进步都是对自己努力的肯定。如果读了文章有收获,不如一起来学习,一起进步吧。传送门刷题神器

你可能感兴趣的:(牛客刷题--斩获offer,面试,排序算法,算法,数据结构)