【剑指offer】题目36 数组中的逆序对

数组中任取两个数字,如果前面的数字大于后面的数字称为一个逆序对

如:1,2,1,2,1 有3个逆序对

思路:知道O(N2)肯定是错的。开始想hash,试图找到O(n)的算法,想了很久,找不到。后来想到排序,用原数组与排好序的数组对比,我写的快排,还是不对。想了几个小时,无奈看答案,原来是用变形的归并排序。排序真是博大精深,换个样子我就想不到了....

在牛客网上AC的代码:脑子不清醒,各种小错,提交了好多遍。

class Solution {
public:
    void myMergeSort(vector<int> &data, int & ans, int l, int r, vector<int> &v)
    {
        if(l >= r) return;
        int m = l + (r - l) / 2;
        myMergeSort(data, ans, l, m, v);
        myMergeSort(data, ans, m + 1, r, v);
        myMerge(data, ans, l, m, r, v);

    }
    void myMerge(vector<int> &data, int & ans, int l, int m, int r, vector<int> &v)
    {
        int n1 = m - l + 1;
        int k = 0, i = l, j = m + 1;
        while(i <= m && j <= r)
        {
            if(data[i] <= data[j])
            {
                v[k++] = data[i++];
            }
            else
            {
                v[k++] = data[j++];
                ans += m - i + 1;
            }
        }
        while(i <= m)
            v[k++] = data[i++];
        while(j <= r)
            v[k++] = data[j++];
        for(k = 0; k < r - l + 1; k++)
            data[k + l] = v[k];
    }
    int InversePairs(vector<int> data) {
        int ans = 0;
        vector<int> v(data.size());
        myMergeSort(data, ans, 0, data.size() - 1, v);
        return ans;
    }
};
时间: 2024-12-27 13:07:11

【剑指offer】题目36 数组中的逆序对的相关文章

剑指offer系列——35.数组中的逆序对??

Q:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000000007 输入描述: 题目保证输入的数组中没有的相同的数字 数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2*10^5 示例1 输入: 1,2,3,4,5,6,7,0 输出: 7 T:引用:https://blog.

剑指Offer对答如流系列 - 数组中的逆序对

面试题51:数组中的逆序对 题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 问题分析 大多数人的第一反应就是顺序扫描整个数组,对每个数字都和后面的数字比较大小,时间复杂度为O(n^2),效率太低. 利用归并排序的思想,先将数组分解成为n个长度为1的子数组,然后进行两两合并同时排好顺序.(在排序的时候计算逆序对) 归并排序是经典排序算法之一,其核心是将待排数组不断细分,然后排序最后再合并,这是经典的分治策略(分

剑指offer系列61---数组中的逆序对

[题目]在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. * [思路]运用归并排序的思想. * 首先将数组分成两个子数组,统计子数组的逆序对: * 再合并,统计整个的逆序对. 1 package com.exe11.offer; 2 3 /** 4 * [题目]在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 5 * [思路]运用归并排序的思想.

剑指offer (36) 数组中的逆序对

题目:在数组中的两个数字如果前面一个数字大于后面一个数字,则这两个数字组成一个逆序对 题解分析: 首先应该想到很简单的一种解法,顺序遍历数组,对每个数,逐个比较该数字和其以后的数字,T(n) = O(n^2) (1)总体的意思就是将数组分成两段,首先求段内的逆序对数量,比如下面两段代码就是求左右两端数组段内的逆序对数量 count += Merge(data, temp, first, mid);//找左半段的逆序对数目 count += Merge(data, temp, mid + 1, e

【剑指offer】旋转数组中的最小值

题目总结: 1.若没有进行旋转,或者说旋转后的效果跟没有旋转是一样的,那么index1指示的值小于index2指示的值,返回index1的值. 2.若是一般性的旋转,那么最小的值旋转后肯定在中间,那么我们就可以从两边向中间夹逼. 3.夹逼的过程中,若 [ index1, middle ] 是有序的,说明这部分子区间没被破坏,旋转所移动的元素都在middle 的后面,那么最小值可定也在后面的部分,令 index1 = middle,继续向后夹逼:同理,若 [ middle ,index2 ] 是有

剑指offer 面试题36—数组中的逆序对

题目: 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数.例如在数组{7,5,6,4}中一共存在5对逆序对,分别是(7,6),(7,5),(7,4),(6,4),(5,4) 基本思想: 解法一:O(n^2) 最简单的想法就是遍历每一个元素,让其与后面的元素对比,如果大于则count++,但是这样的时间复杂度是O(n^2). 解法二:O(nlogn) 归并排序思路: 例如7,5,4,6可以划分为两段7,5和4,6两个子数组 1

剑指Offer对答如流系列 - 数组中数字出现的次数

面试题56:数组中数字出现的次数 题目描述 问题(1)数组中只出现一次的两个数字 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 问题(2)数组中唯一只出现一次的数字 在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次.请找出那个只出现一次的数字. 问题分析 问题(1)分析 在这篇文章剑指Offer对答如流系列 - 二进制中 1 的个数中,我们详细探讨了位运算,其中有重要的一条:两个相同的数异

【算法题目】数组中的逆序对

题目来源:<剑指offer>面试题36 题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这两个数组中的逆序对的总数.例如数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6),(7,5),(7,4),(6,4)和(5,4). 下面把<剑指offer>的分析贴上来:                                                                             代码:

面试题36 数组中的逆序对

题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 1 class Solution { 2 public: 3 int InversePairsCore(vector<int> &data,vector<int>&copy,int start,int end) 4 { 5 if(start==end) 6 { 7 copy[start]=data[start]; 8 return