在求解八数码问题时,因为要进行逆序数的计算判断两个结点的可达性,同奇偶的逆序数才能可达。如果只是八数,暴力解法还好,当数字多了之后如何知道逆序数呢。

题目描述

通过计算八数码节点的逆序数判断。如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如 2431 中,21,43,41,31 是逆序,逆序数是 4,为偶排列。
计算八数码节点的逆序数时将代表空格的 0 去除,如初始状态排列为 (1,3,2,4,5,6,7,8) 逆序数为:0+1+0+0+0+0+0+0=1 即为奇排列
目标状态排列为(1,2,3,8,4,7,6,5) 逆序数0+0+0+4+0+2+1+0=7 即为奇排列,具有同奇或同偶排列的八数码才能移动可达,否则不可达。

思路一

暴力穷举,每次扫描一个数时,遍历后方所有的数,那么这样的代价很大,O(n2)的时间复杂度。

思路二

分治的思想,自上而下划分,将大数组划分为小数组,只到划分到为数组中只有一个时,通过自下而上的排序的过程,计算出本数组中的数与相邻数组的逆序数,其实本质就是归并排序的过程。时间复杂度nlog2n。

那么怎么在归并排序的过程中进行分组呢?
例如下方,先考察相邻数组块的最大值,比较后若左侧大于右侧,则逆序数加上右侧剩余数目(因为两侧数据皆为有序),并加大数填入最终的位置,并将大数所在数组指针向右侧移动。直到指针全部移到最左端。当一侧的数据全部填入之后,将剩余部分填入最前端。

代码实现

作为数组,可以省略“分”的步骤,看成已经将每个数分成一个单位,直接进行“治”的过程。

`int sort(int *b, int start,int step,int num)//排序相邻的数据块
{int result = 0;if (start + step >= num)//如果是最后只剩一个数组块,不需要比较排序{return 0;}else//如果最后剩余两个数组块{int c[20];//临时保存最终排序完成的数组,从大到小排列,共rightend-leftend+1个元素int n = 0;int leftstart = start;int leftend = start + step - 1;//前一个数组的起始和最后int rightstart = start + step;int rightend;//后一个数组的起始和最后if (start + 2 * step > num)//最后一个数组块不足step个{rightend = num-1;}else//两个比较的数据块相同个数都为step个 {rightend = start + 2 * step - 1;}int left = leftend;int right = rightend;while (left>=leftstart&&right>=rightstart){if (b[left] < b[right]){c[n++] = b[right];right--;}else{c[n++] = b[left];left--;result += right - rightstart + 1;}}int begin = start;if (left >= leftstart)//最小的一部分在左侧{begin = left + 1;}else//最小的一部分在右侧{for (int i = rightstart; i <= right; i++){b[begin++] = b[i];}}for (int i = begin; i <= rightend; i++){b[i] = c[--n];}return result;}}
int inverse_number(int *a, int num)//归并排序
{int b[20];for (int i = 0; i < num; i++){b[i] = a[i];}int sum = 0;int step = 1;while (step < num){for (int i = 0; i < num; i =i + 2*step){sum += sort(b, i, step,num);}step = step * 2;}return sum;
}`

优化

当经过一轮排序,所有数据未发生改变即可停止。

逆序数问题(归并排序,C++)相关推荐

  1. ACM_逆序数(归并排序)

    帮挂科 Time Limit: 2000/1000ms (Java/Others) 64bit IO Format: %lld & %llu Problem Description: 冬瓜发现 ...

  2. 逆序数介绍以及算法实现

    前言 线性代数中对于一段数字序列的排列情况有这样一个定义:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. ...

  3. 分治递归逆序数_[模板] 归并排序 逆序数 分治

    归并排序 图来自维基 递归调用的过程需要在脑中模拟清楚 然后是代码的细节问题 多复习多理解 刘汝佳版 #include using namespace std; const int MAXN = 1e ...

  4. 【排序】归并类排序—归并排序(逆序数问题)

    文章目录 前言 归并排序(merge sort) 逆序数 结语 微信公众号:bigsai 数据结构与算法专栏 前言 在排序中,我们可能大部分更熟悉冒泡排序.快排之类.对归并排序可能比较陌生.然而事实上 ...

  5. 八十二、归并排序求取复杂的逆序数

    @Author:Runsen 逆序数,我在很多的面试题都见过,本质上来说难度是比较大,因为如果使用暴力法当数据量一大,必然就会爆掉.你现在就要记住逆序数就是考归并排序. 逆序数 给定一个数组array ...

  6. 【归并排序】-求逆序数算法

    1.归并排序 归并排序是分治法的一种典型应用,应用递归思想,自顶向下思考:先假定MergeSort()可以将一个乱序数组排好序,因此可以开始分(将一个数组平均分成两部分),再治(分别调用MergeSo ...

  7. 【归并排序】求逆序数算法

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序. 一个排列中逆序的总数就称为这个排列的逆序数.逆序数为偶数的排列称为偶排列:逆序数为奇数的排列称为奇排 ...

  8. 逆序数问题,用归并排序而非树状数组求解

    逆序数,结合归并排序. 之前一直用树状数组写的,今天发现归并排序也很好写. https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0e ...

  9. LeetCode 315. 计算右侧小于当前元素的个数(二叉查找树二分查找归并排序逆序数总结)

    文章目录 1. 题目 2. 解题 2.1 二叉查找树 2.2 二分插入 2.3 归并排序 1. 题目 给定一个整数数组 nums,按要求返回一个新数组 counts.数组 counts 有该性质: c ...

最新文章

  1. activity得到service的数据的方法
  2. PyTorch 加载超大 Libsvm 格式数据
  3. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1061:求整数的和与均值
  4. 大话数据结构——查找
  5. Android Canvas绘制带箭头的直线
  6. Commons Collections学习笔记(四)
  7. Visual Studio 窗口的图标、图片资源 $this.Icon 在哪查看
  8. 华为Mate40 RS保时捷设计推8+256GB版本:起售价便宜1000元
  9. 配置映射文件中使用的类的类型别名typeAliases
  10. win10 桌面的的文件都不见了 提示不注销保存都文件都为临时_Windows10隐藏的8个小技巧,每一个都非常实用又高效...
  11. Google kickstart 2013 Practice Round Captain Hammer 题解
  12. MySQL:ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA
  13. 移动端屏幕适配和css美化浏览器自带的滚动条
  14. echarts画关系图,指定有的关系为双向箭头,有的关系为单向箭头
  15. android 语音播放工具,Android简易的仿微信聊天的语音播放控件
  16. python+OpenCv笔记(七):图像的形态学操作(腐蚀与膨胀、开闭运算、礼帽与黑帽)
  17. SQL-查询JIRA中已创建与已解决问题对比报告
  18. 机器学习笔记-利用线性模型进行分类
  19. java计算机毕业设计基于安卓Android的装维助手APP
  20. 【PAT甲级】1095 Cars on Campus (30分)

热门文章

  1. 全国计算机一级可以在手机上报名吗,全国计算机一级过的话能多次报名?
  2. Android phone xp 华为3x,3000mAh大电池 华为荣耀3X续航能力实测
  3. php视频文件上传到服务器,上传和下载图片和视频到服务器
  4. 长春市计算机学校老照片,松江这所学校一百年啦!一组老照片回忆曾经的旧时光…...
  5. html 执行外部js的函数,javascript – Chrome扩展程序:加载并执行外部脚本
  6. rust(25)-皮尔逊相关系数
  7. 趣学python3(30)-字典
  8. 【NLP】darmatch: 一个非常高效的多模式字符串匹配工具
  9. 【机器学习】机器学习中样本不平衡,怎么办?
  10. 温州大学《深度学习》课程课件(一)