当前位置: 首页 > news >正文

【每日一练】图解: 数组中的逆序对

【每日一练】图解: 数组中的逆序对

  • 题目: 数组中的逆序对
    • 示例
    • 初始代码
  • 思路
      • 完整代码:

题目: 数组中的逆序对

题目来源牛客 - 链接在此

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

要求:空间复杂度 O(n),时间复杂度 O(nlogn)
输入描述:题目保证输入的数组中没有的相同的数字
在这里插入图片描述

示例

  • 示例1
    在这里插入图片描述
  • 示例2
    在这里插入图片描述

初始代码

public class Solution {
    public int InversePairs(int [] array) {
        
    }
}

思路

这道题可以用暴力法直接比较,但是明显不满足题目对时间复杂度的要求。
我们从题目要求的时间复杂度中看到logn,则应该敏感,logn说明应该使用分治法。

那么如何分治呢?
我们要找的是逆序对的数量。分治,一般和递归/循环相联系,说明应该分到一个阶段,这里我们要找逆序对,则首先想到应该把数组两两切分到最小(只包含一个元素),然后数组之间进行比较,这样就可以获得逆序对的个数。
在这里插入图片描述

如何比较呢?数组之间应该是互相比较?分别比较?
从分治的一般思路来看,我们对一个整体进行切分之后,要做一些什么事情,得到结果,然后再把这些分割的部分重新整合起来,同时整合结果,最终回到一个整体,并得到一个最终结果,即我们想要的答案。

所以思考:将数组两两分到最小之后,应该进行两两比较,记录逆序数。
在这里插入图片描述
记录逆序数之后,这两个数组应该进行合并。

再思考:如何合并?
直接合并:好像分治并没有什么作用~
在这里插入图片描述
可否排序?对已经比较过的数组在合并的同时排序(归并排序)
可!
在这里插入图片描述
排序后:所有的数组分别是有序的,这样剩下的数组在计算逆序数对的时候可以直接计算前面的数组中比后面大的数。
例如:
在这里插入图片描述
下面用一个返例来让大家体会更深:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里思路已经很清楚啦!

下面再以第三次排序合并为例
简单图解归并排序的实现(掌握的同学可直接跳过~):
在这里插入图片描述

到这里整个题目就很清楚啦!
下面直接上代码~~

完整代码:

/**
     * 数组中的逆序对
     * @param array
     * @return
     */
    public int InversePairs(int [] array) {
        // 分治需要使用递归,因此重新封装到一个方法中
        return merge(array, 0, array.length - 1);
    }

    private int merge(int[] array, int start, int end) {
        // 分到最小(数组中只有一个元素)此时逆序数为0
        if (start >= end) return 0;
        int count = 0;//用于记录逆序数 逆序数=两个带合并数组本身的逆序数+两个数组之间的逆序数
        int mid = (start + end) >> 1;//找到分割点(数组中点)
        count += merge(array, start, mid);//左边部分,递归分割
        count += merge(array, mid + 1, end);//右边部分

        // 归并排序
        int[] tmp = new int[end - start + 1];//使用一个临时数组,存放排序后的元素
        int l = start;//指向待合并的第一个数组首元素
        int r = mid + 1;//指向待合并的第二个数组首元素
        int i = 0;//指向临时数组
        while (l <= mid && r <= end) {
            if (array[l] < array[r]) {//升序,直接复制
                tmp[i] = array[l];
                i++;
                l++;
            } else {//后面数组中的数小于前面数组中的数->逆序,记录逆序数+1
                count = (count + (mid + 1 - l)) % 1000000007;
                tmp[i] = array[r];
                r++;
                i++;
            }
        }
        //多余的元素复制到临时数组中
        while (l <= mid) {
            tmp[i++] = array[l++];
        }
        while (r <= end) {
            tmp[i++] = array[r++];
        }
        //将临时数组复制给array
        for (int j = 0; j < i; j++) {
            array[j + start] = tmp[j];
        }
        return count;
    }

关注我!一起加入每日一练吧!~

在这里插入图片描述

相关文章:

  • 【Django】开发日报_8_Day:手机号码管理系统(6)
  • Quartz框架之Job和JobDetail(2)
  • C语言刷题(二)
  • 【毕业设计】机器学习股票大数据量化分析与预测系统 - python 毕业设计
  • Ubuntu下安装opencv
  • 手把手带你刷好题(牛客刷题⑦)
  • Java保证线程安全的方式有哪些?
  • 《数据结构》队列及其经典面试题
  • 计算机图形学(十一):真实感图形(光照模型、材质模型)
  • 【云原生】Hadoop HA on k8s 环境部署
  • 四元数是什么
  • 大衣哥家里再添喜事,生产厂家免费送给他一辆新车
  • 爬取疫情数据并存到mysql数据库
  • 场景应用:网络的子网掩码为255.255.240.0,它能够处理的主机数是多少?
  • Qt5开发从入门到精通——第七篇六节( 图形视图—— 图元的旋转、缩放、切变、和位移)
  • 77. Combinations
  • Android优雅地处理按钮重复点击
  • HTTP 简介
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • Netty源码解析1-Buffer
  • PHP 的 SAPI 是个什么东西
  • Redux系列x:源码分析
  • storm drpc实例
  • Webpack 4x 之路 ( 四 )
  • 从零开始学习部署
  • 大数据与云计算学习:数据分析(二)
  • 马上搞懂 GeoJSON
  • 那些被忽略的 JavaScript 数组方法细节
  • 为视图添加丝滑的水波纹
  • postgresql行列转换函数
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​queue --- 一个同步的队列类​
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • # 安徽锐锋科技IDMS系统简介
  • # 透过事物看本质的能力怎么培养?
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • $.ajax()参数及用法
  • $.proxy和$.extend
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (14)Hive调优——合并小文件
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (第一天)包装对象、作用域、创建对象
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (原創) 物件導向與老子思想 (OO)
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .NET Micro Framework 4.2 beta 源码探析
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • /run/containerd/containerd.sock connect: connection refused
  • @RequestMapping 的作用是什么?
  • @Valid和@NotNull字段校验使用
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)