面试题51. 数组中的逆序对

  在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

示例 1:

输入: [7,5,6,4]
输出: 5

限制:

0 <= 数组长度 <= 50000

归并排序简介:

    归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

  将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并(如下图)。

  归并排序时间复杂度为NlogN,仅次于快速排序(点击链接可看我之前发过的快排博文),为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列

                  

归并排序举例:

    如设有数列{6,202,100,301,38,8,1}

    初始状态:6,202,100,301,38,8,1

    第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;

    第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;

    第三次归并后:{1,6,8,38,100,202,301},比较次数:4;

    总的比较次数为:3+4+4=11;

    逆序对数为14对;

归并排序求逆序对数:具体思路是,在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数(也可以用 树状数组来求解)

代码解析:

 class Solution {
//归并排序:
int reversepairs = 0;//逆序对数
public int[] mergeSort(int[] nums, int left, int right){//归并排序函数
if (left == right)//如果左边界等于右边界,说明数组只有一个值,不用排序
return new int[] { nums[left] };
int mid = (right + left) / 2;//将数组分为两半 int[] leftArr = mergeSort(nums, left, mid); //左有序数组
int[] rightArr = mergeSort(nums, mid + 1, right); //右有序数组
int[] newNum = new int[leftArr.length + rightArr.length]; //新的有序数组 int m = 0, i = 0, j = 0;
//挨着挨着比较从左右两边的排好序的数组中从头开始比较,谁小就先放谁进新的有序空数组
while (i < leftArr.length && j < rightArr.length){//直到左右两个有序数组有一个的遍历下标超出该数组的序列尾部
if(leftArr[i] <= rightArr[j])//左序列的元素小,就把左序列的该元素放入新的空的有序数组中
newNum[m++] = leftArr[i++];
else{//右序列的元素小,就把右序列的该元素放入新的空的有序数组中
newNum[m++] = rightArr[j++];
reversepairs += leftArr.length - i;//左边序列数组中还有leftArr.length-i个元素大于rightArr[j],所以这也是该区间的逆序对数 }
}
while (i < leftArr.length)//如果左序列的元素还有剩余的元素没放进新的空数组中,就把左序列剩余元素放入新的空的有序数组中
newNum[m++] = leftArr[i++];
while (j < rightArr.length)//如果右序列的元素还有剩余的元素没放进新的空数组中,就把右序列剩余元素放入新的空的有序数组中
newNum[m++] = rightArr[j++];
return newNum;
}
public int reversePairs(int[] nums) {//入口函数
if(nums.length == 0)//如果给定的是个空数组,据题意返回0
return 0;
int[] newNums = mergeSort(nums, 0, nums.length - 1);//调用归并排序函数,返回一个有序的数组
return reversepairs;//返回逆序对数
}
}

    

归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对的更多相关文章

  1. LeetCode 面试题51. 数组中的逆序对

    面试题51. 数组中的逆序对 题目来源:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/ 题目 在数组中的两个数字,如果 ...

  2. 力扣Leetcode 面试题51. 数组中的逆序对 - 归并排序

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: 0 <= ...

  3. 《剑指offer》面试题51. 数组中的逆序对

    问题描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5   限制: ...

  4. 剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组

    剑指 Offer 51. 数组中的逆序对 Offer_51 题目描述 方法一:暴力法(双层循环,超时) package com.walegarrett.offer; /** * @Author Wal ...

  5. 微软面试题:剑指 Offer 51. 数组中的逆序对 Hard 出现次数:3

    题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对. 输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: ...

  6. 【Java】 剑指offer(51)数组中的逆序对

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成 ...

  7. MergeSort归并排序和利用归并排序计算出数组中的逆序对

    首先先上LeetCode今天的每日一题(面试题51. 数组中的逆序对): 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. ...

  8. 九度OJ 1348:数组中的逆序对 (排序、归并排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2777 解决:656 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组 ...

  9. php实现数组中的逆序对(归并排序实现:排序 辅助数组)

    php实现数组中的逆序对(归并排序实现:排序 辅助数组) 一.总结 这题用归并排序  线段树   树状数组 等操作的复杂度应该都是小于n方的 二.php实现数组中的逆序对 题目描述 在数组中的两个数字 ...

随机推荐

  1. Java GC(垃圾回收)机制知识总结

    目录 Java GC系列 Java关键术语 Java HotSpot 虚拟机 JVM体系结构 Java堆内存 启动Java垃圾回收 Java垃圾回收过程 垃圾回收中实例的终结 对象什么时候符合垃圾回收 ...

  2. HDU - 3068 最长回文manacher马拉车算法

    # a # b # b # a # 当我们遇到回判断最长回文字符串问题的时候,若果用暴力的方法来做,就是在字符串中间添加 #,然后遍历每一个字符,找到最长的回文字符串.那么马拉车算法就是在这个基础上进 ...

  3. EntityFramework Core 3.x添加查询提示(NOLOCK)

    前言 前几天看到有园友写了一篇关于添加NOLOCK查询提示的博文<https://www.cnblogs.com/weihanli/p/12623934.html>,这里呢,我将介绍另外一 ...

  4. arcgis连接oracle发布服务,提示数据未注册到服务器,手动注册服务器失败

    arcgis连接oracle数据库发布服务时候,分析之后提示:数据未注册到服务器上. 手动注册之后提示:数据客户端没有正确配置.实际上数据库客户端已经安装完成也可以使用. 设置 PATH 环境变量(仅 ...

  5. docker下centos7编译安装ffmpeg

    1.安装基础命令 docker下精简版centos没有make等命令,先安装: yum -y install gcc automake autoconf libtool make yum instal ...

  6. 基于.NetCore3.1搭建项目系列 —— 使用Swagger导出文档 (番外篇)

    前言 回顾之前的两篇Swagger做Api接口文档,我们大体上学会了如何在net core3.1的项目基础上,搭建一套自动生产API接口说明文档的框架. 本来在Swagger的基础上,前后端开发人员在 ...

  7. Synchronized锁机制和ReentrantLock

    Synchronized Java中的每个对象都可以作为锁. 普通同步方法,锁是当前实例对象. 静态同步方法,锁是当前类的class对象. 同步代码块,锁是括号中的对象. 锁的内部机制 一般锁有4种状 ...

  8. Java常用类__装箱/拆箱

    以下是常用的各两种方法(各类提供了构造方法,静态方法) 一.基本数据类型 转化为 包装类(装箱) 例:int i=10: Integer num=i;//num=10 二.包装类 转化为  基本数据类 ...

  9. 【cs224w】Lecture 3 - Motif, Graphlet 及 结构性角色

    目录 Network Motifs Configuration Model Graphlets How to Find Motifs and Graphlets Structural Roles 转自 ...

  10. Oracle ROWNUM用法

    很多朋友应该跟我一样有个疑问,为什么rownum > 5 的时候会查不到一条数据,用rownum < 5就可以查到数据,明明查询所有的时候rownum有很多啊,小朋友,你是不是有很多问号? ...