逆序对之冒泡和归并排序

  • 前言
  • 一、例题
    • 1、原题
      • A.题目
      • B.示例
  • 二、题解
    • 1、冒泡法
      • A.Code
      • B.Estimate
    • 2、基于分治的二路归并
      • A.Code
      • B.Estimate
  • 总结
  • 参考文献

前言

逆序对是一种常见的需求,比如行列式降阶法中确定正负号时需要逆序对的个数。

一、例题

1、原题

A.题目

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

B.示例

示例 1:
输入: [7,5,6,4]
输出: 5

二、题解

分析该问题的核心----逆序对,转化成升序排序时,逆序对的个数就是两数之间的交换次数。而这种两数之间按大小关系交换的排序算法就有冒泡法基于分治的二路归并法

1、冒泡法

Core:相邻两元素之间通过比较大小来交换位置。

A.Code

 /*** 剑指offer 51 数组中的逆序对** @param nums* @return*/public int reversePairs(int[] nums) {//core:将nums进行冒泡升序排序,每对逆序对都会交换一次,记录排序完交换的次数。int count = 0;int n = nums.length;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - 1 - i; j++) {if (nums[j] > nums[j + 1]) {int temp = nums[j];nums[j] = nums[j + 1];nums[j + 1] = temp;count++;}}}return count;}

B.Estimate

1)Time -> O(n2),找每一个元素的逆序对需要O(n),一共有n个元素。
2)Space -> O(1),只用到常数个辅助空间。

2、基于分治的二路归并

思想:通过分治,将长度为n的无序表分为n个长度为1的有序表,然后相邻有序表之间两两归并得到一个新的有序表。反复归并,最终得到一个长度为n的有序表。
Core:
一个相对有序的表 + 相邻有序的表 + 辅助数组 = 一个相对有序的表。(利用了相对有序+辅助数组快速合并成一个相对有序的表,而减少重复比较时间。

A.Code

 //用于记录有多少此交换private int count = 0;//归并必须要用到的辅助数组private int[] temp = null;public int reversePairs(int[] nums) {//core:将nums进行归并排序,减少时间复杂度。int n = nums.length;temp = new int[n];MergeSort(nums, 0, n - 1);return count;}//归并的核心逻辑private void Merge(int[] nums, int low, int high) {//计算中间值,便于归并左右段。int mid = (high + low) / 2;//把数据复制到辅助数组。for (int i = low; i <= high; i++) {temp[i] = nums[i];}//开始归并两段数据int i, j, k;for (i = low, j = mid + 1, k = i; i <= mid && j <= high; k++) {if (temp[i] > temp[j]) {nums[k] = temp[j++];} else {//左边的值进入数组,可能已经有很多右边比较小的值已经进入数组了,所以存在逆序对。count += j - (mid + 1);nums[k] = temp[i++];}}//把剩下每比较的一段数据直接加在后面。while (i <= mid) {//同理,说明右边的值全部小于此刻i及i后面的值,即存在逆序对。nums[k++] = temp[i++];count += j - (mid + 1);}while (j <= high) nums[k++] = temp[j++];}//基于分治来归并private void MergeSort(int[] nums, int low, int high) {//只要还没有把数据分成只有一个的时候,就递归分组及归并。if (low < high) {int mid = (high + low) / 2;MergeSort(nums, low, mid);MergeSort(nums, mid + 1, high);//最后把low -- high的两段数组归并Merge(nums, low, high);}}

注:模拟归并

初始元素 一趟归并后 两趟归并后 三趟归并后
[65] [49] [97] [38] [88] [49 65] [38 97] [88] [38 49 65 97] [88] [38 49 65 88 97]

B.Estimate

1)Time -> O(nlog2n),一趟归并需要O(n),一共需要log2n趟归并。
2)Space -> O(n),需要O(n)大小的辅助数组才能发挥两相邻表的有序性。

总结

1)冒泡排序
2)基于分治的二路归并排序
3)转化问题,逆序对个数 -> 排序交换次数。

参考文献

[1] Leetcode 原题

逆序对之冒泡和归并排序相关推荐

  1. 逆序对算法c语言,归并排序求逆序对的代码(C语言)

    #include #include #define MAX 32767 int merge(int *array, int p,int q,int r) { //归并array[p...q] 与 ar ...

  2. 逆序对的数量(归并排序模板y神)

    #include<iostream> using namespace std; typedef long long LL; const int N = 100010; int n; int ...

  3. 泛 归并排序 及 逆序对

    今天写一个归并排序的模板,返回值为该序列的逆序对数 基本思路 归并排序就是利用二分的思想,将区间无限递归二分,直到当前划分区间只包含一个元素或没有元素的时候(我们认为这个序列是自动有序的),我们回溯到 ...

  4. python 归并排序,合并有序数组,逆序对个数

    归并排序,合并有序列表,求逆序对个数 之所以将标题中三者放一起是因为它们有密不可分的关系. 合并有序列表 定义一个空列表 li 用来存放排序后的值; 定义两个 cursor lc 和 rc,分别指向左 ...

  5. POJ-排序-归并排序与逆序对

    排序:归并排序与逆序对 一.概念 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序 ...

  6. 算法?从这里开始(2)——递归,归并排序,小和问题,逆序对问题

    目录 1.递归 2.归并排序 3.小和问题 4.逆序对问题 1.递归 在一个数组中找最大值,最直观的方式的是遍历,当然可以,但我们这次要用递归的方式.怎么做哪? 假设我们有一个数组,最左边元素我们记为 ...

  7. 学归并排序和逆序对,这篇文章就够了!!!归并排序和逆序对超详细整理!

    目录 1.归并排序 2.逆序对 3.例题 1.归并排序 (1).介绍 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(DivideandConquer)的一个非常典型的应用.将已有 ...

  8. vb.net中递归退到最外层_数组中的逆序对

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

  9. 逆序对(洛谷-P1908)

    题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为"逆序对"的 ...

最新文章

  1. 只要5分钟用数据可视化带你看遍11月份新闻热点事件
  2. java百度api人脸识别_百度人脸识别api demo
  3. jSearch(聚搜) v1.1.0 发布,全新视觉体验
  4. Python自动化测试(1)-自动化测试及基本技术手段概述
  5. wave文件 fft_STM32F103 如何实现 FFT?
  6. 动态生成JSP文件,并调用JSP程序
  7. 雷军:如果程序人生的话,这条路太漫长
  8. (转)Android属性设置android:noHistory=true
  9. 【Python3网络爬虫开发实战】1.2.6-aiohttp的安装
  10. sql server生成不重复的时间字符串
  11. Java建造者模式(Builder模式)
  12. 什么是模型?什么是数学模型?
  13. 解决打印机问题的方法
  14. 二阶系统响应指标图_二阶系统单位阶跃响应.ppt
  15. python selenium 下载附件通过oss上传
  16. python系列:玩转大家来找茬
  17. uva10105 - Polynomial Coefficients(多项式系数)
  18. 小说APP开发,实现小说阅读的翻页动画
  19. 围观历史上最著名的十大思想实验,一起来疯狂思考一下
  20. vue简易微前端项目搭建(二):子项目模板及项目脚手架搭建

热门文章

  1. 高考最后17天,家长最关心的11个问题和答案都在这
  2. 1031 查验身份证 (15分)
  3. springcloud解决运行出现Failed to determine a suitable driver class
  4. 微信社群私域流量建设流程运营规划方案SOP
  5. 袋鼠云正式入驻中国信创服务社区,直播首秀等你来看!
  6. 如何让设计师不成为机器_想要成为最好的设计师? 针对您不知道的内容进行设计。...
  7. OpenCV——PS 滤镜, 曝光过度
  8. 著作权与版权如何进行合理区分
  9. load Sdk stackflow.md
  10. ArtifactDescriptorException:Failed to read artifact descriptor for org.freem