[饭后算法系列] "头尾移动" 排序列表
1. 问题
一个乱序列表(list), 只支持两种操作: 把一个元素移动到头部, 或者把一个元素移动到尾部. 需要设计一种算法, 使得移动次数最少而使列表有序
举两个例子:
1. {3,5,7,1,9,10,8}. 最少需要移动3次: 1移动到头部, 9移动到尾部, 10移动到尾部
2. {6,5,4,3,2,1}. 最少需要移动5次: 将2,3,4,5,6依次移动到尾部, 或者将5,4,3,2,1依次移动到头部
2. 分析
这题和其他算法不一样的地方在于求严格的最优移动次数, 而不是移动次数的复杂度, 也不要求整体算法的复杂度, 因此只要考虑怎么最小化移动次数即可
3. 暴力法
暴力法是算法的一个标杆, 表明了"最差"的算法需要移动多少次, 这可以给我们思考最优算法提供一个直观的界线
拿这道题目来说, 用暴力法怎么解用例1中的{3,5,7,1,9,10,8}?
我们可以无视任何优化, 简单地把列表中最小的数字(1)移动到尾部, 再将次小的数字(3)移动到尾部, 这样依次将5,7,8,9,10移动到尾部, 就完成了整个列表的排序, 总共需要移动n次, n为列表的元素个数.
也就是说, 对于一个最优算法, 移动次数一定是小于n的
4. 算法优化
4.1 标准化
根据暴力法我们可以发现, 我们需要知道每个数字在列表中的大小关系, 也就是需要知道1是最小的, 3是次小的
所以我们需要把列表标准化, 标准化后的列表元素, 是原列表元素从小到大的序号. 即3在原数组中第2大, 所以3标准化为2. 以此类推, 用例1标准化为: {2,3,4,1,6,7,5}
下面所有的操作都针对标准化后的列表
4.2 算法主体
1. 找到列表中最长的 '步进1递增子序列', 比如用例一中的2,3,4,5. 注意这里一定要步进为1, 所以虽然2,3,4,6,7是最长的递增子序列, 但是4->6的步进不为1, 所以不考虑
2. 假设找到的最长步进1递增子序列为 i, i+1, ..., j, (长度为k) 那么剩下的工作就是把其他元素归位:
2.1 依次把 i-1, i-2, ..., 1移动到头部
2.2 依次把 j+1, j+2, ..., n移动到尾部
总共的移动次数为 n-k
关键字: 算法, 排序, 列表
[饭后算法系列] "头尾移动" 排序列表的更多相关文章
- 排序算法系列:选择排序算法JAVA版(靠谱、清晰、真实、可用、不罗嗦版)
在网上搜索算法的博客,发现一个比较悲剧的现象非常普遍: 原理讲不清,混乱 啰嗦 图和文对不上 不可用,甚至代码还出错 我总结一个清晰不罗嗦版: 原理: 从数组头元素索引i开始,寻找后面最小的值(比i位 ...
- 算法系列:Shell 排序
Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...
- [饭后算法系列] 数组中"和非负"的最长子数组
1. 问题 给定一列数字数组 a[n], 求这个数组中最长的 "和>=0" 的子数组. (注: "子数组"表示下标必须是连续的. 另一个概念"子 ...
- 数据结构与算法系列——排序(4)_Shell希尔排序
1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...
- 三白话经典算法系列 Shell排序实现
山是包插入的精髓排序排序,这种方法,也被称为窄增量排序.因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元 ...
- 排序算法系列:快速排序算法JAVA版(靠谱、清晰、真实、可用、不罗嗦版)
在网上搜索算法的博客,发现一个比较悲剧的现象非常普遍: 原理讲不清,混乱 啰嗦 图和文对不上 不可用,甚至代码还出错 为了不误人子弟耽误时间,推荐看一些靠谱的资源,如[啊哈!算法]系列: https: ...
- 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL
树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构. a.树是n ...
- 排序算法系列:插入排序算法JAVA版(靠谱、清晰、真实、可用、不罗嗦版)
在网上搜索算法的博客,发现一个比较悲剧的现象非常普遍: 原理讲不清,混乱 啰嗦 图和文对不上 不可用,甚至代码还出错 我总结一个清晰不罗嗦版: 原理: 和选择排序类似的是也分成“已排序”部分,和“未排 ...
- 数据结构和算法(Golang实现)(25)排序算法-快速排序
快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...
随机推荐
- java接口与抽象类的区别
接口可以是标志接口,里面没有任何常量和方法. 抽象类不一定必须有抽象方法,也可也没有方法,但含抽象方法的类必须被声明为抽象类. 在抽象层次结构中,Java接口在最上面,然后紧跟着抽象类,然后是一般类. ...
- Android TagFlowLayout完全解析 一款针对Tag的布局(转)
一.概述 本文之前,先提一下关于上篇博文的100多万访问量请无视,博文被刷,我也很郁闷,本来想把那个文章放到草稿箱,结果放不进去,还把日期弄更新了,实属无奈. ok,开始今天的博文,今天要说的是Tag ...
- SharedPreferences的工具类,使用起来方便、快捷
SharedPreferences的工具类,使用起来方便.快捷:上代码:import android.content.Context;import android.content.SharedPref ...
- 06-自定义Attribute标记案例
自定义Attribute: 1)Attribute都从System. Attribute类继承,类名一般以Attribute结尾 2) 标记类的用途—AttributeUsage标记(标记的标记):A ...
- (转)background-position—CSS设置背景图片的位置
background-position :在 CSS 中通过 background-position 属性可以调整背景图片的位置.因为在默认情况下背景图片都是从设置了 background-posit ...
- 秒味课堂Angular js笔记------Angular js中的工具方法
Angular js中的工具方法 angular.isArray angular.isDate angular.isDefined angular.isUndefined angular.isFunc ...
- JavaScript--基本包装类型+Math对象
1. 基本包装类型 1)为了便于操作基本类型值,ECMAScript提供了3个特殊的引用类Boolean, Number, String 每当读取一个基本类型值的时候,后台就会创建一个对应 ...
- C++拾遗(八)类——概念、定义与实现
Class与Struct 区别在于class默认访问类型是private,struct默认访问类型是public. 另外在使用习惯上,struct只用来表示纯粹的数据对象或没有私有部分的类. 类中的内 ...
- IntelliJ IDEA 12 创建Web项目 教程 超详细版
IntelliJ IDEA 12 新版本发布 第一时间去官网看了下 黑色的主题 很给力 大体使用了下 对于一开始就是用eclipse的童鞋们 估计很难从eclipse中走出来 当然 我也很艰难的走 ...
- sublime在Mac osx下安装z-codeing(即emmet)
sublime安装插件可以根据插件名称通过package control就可以很方便的安装好.但是sublime没有默认安装package control,所以我们必须先安装它. 安装package ...