题解 | #数组中的逆序对# 归并排序 : 递归, 二分

数组中的逆序对

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5

class Solution {
private:
    const int kmod = 1000000007;
public:

    void merge_sort__(vector<int>& arr, vector<int>& tmp, int l, int r, int& ret)
    {
        if(l>=r)
        {
            return;
        }

        int mid = (r+l)/2;

        // 二分后 再分别 divide
        merge_sort__(arr, tmp, l, mid, ret);
        merge_sort__(arr, tmp, mid+1, r, ret);

        // 分完之后的 治 最底层是  前后半个区间里的 首两个元素的合并
        merge__(arr, tmp, l, r, mid, ret);
    }

    void merge__(vector<int>& arr, vector<int>& tmp, int l, int r, int mid, int& ret)
    {
        // ret 保存 逆序对数 取余的答案

        // 刚才提到在函数内部开辟额外空间的做法很不好。因为这样会涉及到频繁的构建 vector 和析构vector,所以比较好的做法是:直接在最外层开辟一个足够大的数组,然后传引用到函数。
        // vector<int> tmp(r-l+1); // 两部分的总长度
        int i = l, j = mid+1, k=0; // i 和 j各自从 首元素开始

        while(i<=mid && j<=r)
        {
            // 比较大小
            if(arr[i]<arr[j])
            {
                tmp[k++] = arr[i++];
            }
            else
            { // i<j 但元素值相反 是逆序
                tmp[k++] = arr[j++];
                // ret++;
                // miao  由于 [l, mid] [mid+1, r] 已经是各自有序的 所以当a[i]>a[j]
                // 那么从i 道mid 这 mid-i+1 计几个元素和j 都可构成逆序对
                ret += (mid-i+1);

                ret %= kmod;
            }
        }

        // 剩余的元素全放在tmp后面 这是指两半 元素不等的情况
        while(i<=mid)
        {
            tmp[k++] = arr[i++];
        }
        while(j<=r)
        {
            tmp[k++] = arr[j++];
        }

        //再赋值给 arr本身 才能保证每次归并 两部份都是有序

        for(int i=l, k=0; i<=r; ++i, ++k)
        {
            arr[i] = tmp[k]; // 注意这里 赋值回去时还在 arr[l,r] 内 但tmp 每次只是用了前(r-l+1)的地方  
        }

    }

    // 暴力枚举 会超时
    // 官解二: 归并排序的思想
    int InversePairs(vector<int> data) {
        int n = data.size();
        vector<int> tmp(n); //直接在这里开个中间变量 否则放在内部 还会超时
        int cnt = 0;

        merge_sort__(data, tmp, 0, n-1, cnt);
        
        return cnt;
        
    }
};

全部评论

相关推荐

找工作勤劳小蜜蜂:自我描述部分太差,完全看不出想从事什么行业什么岗位,也看不出想在哪个地区发展,这样 会让HR很犹豫,从而把你简历否决掉。现在企业都很注重员工稳定性和专注性,特别对于热爱本行业的员工。 你实习的工作又太传统的it开发(老旧),这部分公司已经趋于被淘汰,新兴的互联网服务业,比如物流,电商,新传媒,游戏开发和传统的It开发有天然区别。不是说传统It开发不行,而是就业岗位太少,基本趋于饱和,很多老骨头还能坚持,不需要新血液。 工作区域(比如长三角,珠三角,成渝)等也是HR考虑的因素之一,也是要你有个坚定的决心。否则去几天,人跑了,HR会被用人单位骂死。
点赞 评论 收藏
分享
Rac000n:淘天-客户运营部-AI研发工程师,智能客服方向,暑期实习招聘,欢迎联系
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务