[饭后算法系列] "头尾移动" 排序列表
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 ...
随机推荐
- Zend框架2入门(二) (转)
Zend框架2使用一个模块系统,和你组织内每个你的主应用程序特定代码模块.骨架提供的应用程序模块是用于提供引导,错误和路由配置到整个应用程序.它通常是用来提供应用水平控制器,比如说,应用程序的主页,但 ...
- C# string.Format谨慎使用
string.Format string.Format在处理文本的时候很有用处,但是在使用占位符的时候一定要注意内容中的特殊字符{}. 示例 string.Format("你好{0},这是{ ...
- 简单水池&&迷宫问题
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; int ...
- 执行oracle函数的四种方法
1.在定义函数时:如果有参数,则参数可有类型但是不加长度. 2.在执行函数: var/variable var_name var_type(如果数据类型是number则没有长度,如果数据类型是varc ...
- ruby 知识点
$LOAD_PATH 执行 require 读取文件时搜索的目录名数组,也可以写作 $: 创建 URI 的时候可以直接这样 URI("http://www.dy2018.com/i/9751 ...
- 数据库的事务处理必须满足ACID原则,ACID分别是指什么
http://blog.csdn.net/dingxingmei/article/details/39270375
- FTP链接mac
mac下一般用smb服务来进行远程文件访问,但要用FTP的话,高版本的mac os默认关掉了,可以用如下命令打开: sudo -s launchctl load -w /System/Library/ ...
- php插入转义与查找转义
//转义用于查找 function deepslashes($data) { //判断data表现形式 if(empty($data)) { return $data; } return is_arr ...
- zepto源码研究 - ajax.js($.ajaxJSONP 的分析)
简要:jsonp是一种服务器和客户端信息传递方式,一般是利用script元素赋值src来发起请求.一般凡是带有src属性的元素发起的请求都是可以跨域的. 那么jsonp是如何获取服务器的数据的呢? j ...
- 数据库SQLite在Qt5+VS2012使用规则总结---中文乱码
VS2012默认格式为 "GB2312-80",而有时我们用到字符串需要显示中文时,就会出现乱码.下面仅就Qt5和VS2012中使用数据库SQLite时,做一个简单的备忘录 #in ...