首页 > 其他分享 >【剑指Offer】35、数组中的逆序对

【剑指Offer】35、数组中的逆序对

时间:2023-06-21 23:33:47浏览次数:47  
标签:数字 Offer int 35 数组 序列 array 逆序

【剑指Offer】35、数组中的逆序对

题目描述:

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

输入描述:

题目保证输入的数组中没有的相同的数字数据范围:

  • 对于%50的数据,size<=10^4
  • 对于%75的数据,size<=10^5
  • 对于%100的数据,size<=2*10^5
      解题思路:

本题一个最容易想到的解法是暴力解法,顺序扫描整个数组,每扫描到一个数字时,逐个比较该数字与后面的数字的大小关系,统计逆序对的个数,假设数组中有n个数字,则每个数字都要和O(n)个数字做比较,因此,这个暴力解法的时间复杂度为O(n^2)。

一般情况下,最容易想到的往往不是最优解法。在这里,我们采用分治的思想,类比归并排序算法来分析此题。

首先将数组分隔成子数组,统计出子数组内部逆序对数目,然后再统计相邻子数组之间的逆序对数目,统计过程中还需要对数组进行排序,这实际上就是归并排序的过程。主要考虑的是合并两个有序序列时,计算逆序对数。对于两个有序升序序列,设置两个下标分别指向开始位置,每次比较两个指针对应的值,如果第一个序列当前值大于第二个序列当前值,则有第一个序列“当前长度”个逆序对。

这看起来好像比较拗口,但是从代码中可以直观看出。

举例:

编程实现(Java):

public class Solution {
    int res=0;
    public int InversePairs(int [] array) {
        //数组中的逆序对,归并排序
        if(array==null || array.length==0)
            return 0;
        findInversePairs(array,0,array.length-1);
        return res%1000000007;
    }
    public void findInversePairs(int[] array,int low,int high){
        if(low<high){
            int mid=low+(high-low)/2;
            findInversePairs(array,low,mid); //左一半递归
            findInversePairs(array,mid+1,high); //右一半递归
            //merge
            merge(array,low,mid,high);
        }
    }
    public void merge(int[] array,int low,int mid,int high){
        int i=low,j=mid+1;
        int[] temp=new int[high-low+1];
        int k=0;
        while(i<=mid && j<=high){
            if(array[i]<=array[j])
                temp[k++]=array[i++];
            else {   //大于,说明是逆序
                temp[k++] = array[j++];
                res += (mid - i + 1);
                res = res%1000000007;
            }
        }
        while(i<=mid)
            temp[k++]=array[i++];
        while(j<=high)
            temp[k++]=array[j++];

        for(i=0;i<temp.length;i++)
            array[low+i]=temp[i];
    }
}

标签:数字,Offer,int,35,数组,序列,array,逆序
From: https://www.cnblogs.com/bujidao1128/p/17497301.html

相关文章

  • 一起被裁,朋友背着我拿了5个大厂offer,我坐不住了……
    前言同样在去年年底被裁,为什么我的一个朋友拿到华为、阿里巴巴、字节跳动、拼多多、百度等5家大厂的offer,而我连一个面试的机会都没有。在这之后我又尝试投了不下于十几次的简历,结果都是了无音讯。我实在是坐不住了,就去咨询了下我这个朋友,他说除了硬实力,软技巧也同样重要。下面就是......
  • TMS320F28335光伏并网逆变器生产资料(另有离网状态 ),包含(原理图/PCB/
    TMS320F28335光伏并网逆变器生产资料(另有离网状态),包含(原理图/PCB/源代码,说明文挡),无实物。YID:3128609798582139......
  • 华为海思HI 3559A 超强算力,整机解决方案 华为海思HI 3559A 超强算力,整机解决方案。
    华为海思HI3559A超强算力,整机解决方案华为海思HI3559A超强算力,整机解决方案。ID:693000598403032808......
  • Armsom推出工规级RK3588J-Core(armsom P1 Core) 8K 智能NVR核心板**
    ArmsomP1Core板载RockchipRK3588J新一代工业级八核64位处理器;采用工业级芯片、精密元器件和BTB连接器,支持宽温温度-40°C~85°C长时间稳定运行;支持ARMPC、边缘计算、云服务器、智能NVR等相关领域;提供10年+超长供货期和完善的技术资料,用户可自主深度化定制。八核工业级处理器RK......
  • RK3588平台产测之ArmSoM产品高温环境测试
    1.简介专栏总目录ArmSoM团队在产品量产之前都会对产品做几次专业化的功能测试以及性能压力测试,以此来保证产品的质量以及稳定性优秀的产品都要进行严苛的多次全方位的功能测试以及性能压力测试才能够经得起市场的检验本文概述RK3588平台产测之ArmSoM-W3高温测试2.......
  • Java面试题集(131-135)
    131、请对以下JavaEE中的名词进行解释答:容器:容器为JavaEE应用程序组件提供了运行时支持。容器提供了一份从底层JavaEEAPI到应用程序组件的联合视图。JavaEE应用程序组件不能直接地与其它JavaEE应用程序组件交互。它们通过容器的协议和方法来达成它们之间以及它们与平台服......
  • Java面试题集(116-135)
    Java程序员面试题集(116-135)摘要:这一部分讲解基于Java的Web开发相关面试题,即便在Java走向没落的当下,基于Java的Web开发因为拥有非常成熟的解决方案,仍然被广泛应用。不管你的Web开发中是否使用框架,JSP和Servlet都是一个必备的基础,在面试的时候被问到的概率还是很高的。116、说出Servl......
  • 迅为视频 | RKNPU2 从入门到实践RK3568/RK3568开发板教程
     迅为基于瑞芯微RK3568和RK3588处理器设计开发的两款开发板都自带NPU,RK3568自带1T算力的NPU、RK3588自带6T算力的NPU,且这两款开发板使用的都是RKNPU2。    (RKNPU发展历程) RKNPU2较RKNPU1有较大的提升,但市面上关于这方面的资料却寥寥无几,导致很多想学习这方面知识的小......
  • 期末考试YTU4035: Shmily(数学,等差数列)
    考试的时候看到这道题一眼前缀和,但是想了想要枚举每个区间是不是复杂度有点高,还是交上去了不出意外的 $TLE$ 了,想了十来分钟还是没想到怎么优化,考完问了一下大佬,原来用等差数列1ms就能过,听说双指针0ms(蒟蒻的我呜呜)众所周知等差数列的前$N$项和是$S$=a1 *n+(n*(n......
  • 【剑指 Offer】数组中重复的数字(C++_Easy_遍历/哈希/快排/原地)
    题目在一个长度为n的数组nums里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。测试样例输入:[2,3,1,0,2,5,3]输出:2或3限制2<=n<=100000题解题解一:遍历对vector容器......