1 题目描写叙述:

有一个数组:2,1,4,3。对于数组,有一种操作op(idx):将该index相应的数字移到首位。比方:

op(3):  2 1 43 -> 3 2 1 4

op(1):  3 2 14 -> 2 3 1 4

op(2):  2 3 1 4 -> 1 2 3 4

问对于给定的数组,数组各个元素是随意的整数。可能有反复值。须要多少次OP操作,才干使得数组有序?

对于上面的样例,须要3次就可以。

2. 问题解析:

最坏的情况须要 n 次就够了。第 i 次找到数组中倒数第 i 大的数,然后进行OP操作,最后一定会使得该数组是有序的。

可是要最少几次。怎样解决?

2.1 时间:O(n^2)  空间:O(1)

对于 2 1 4 3,4肯定不须要OP。接下来对于3,必须要OP。变成了 3 2 1 4。假设3进行OP了,那么其它小于3的数(1,2)都须要进行OP的,否则不能跑到 3 的前面去。

再比方 2 1 6 3 7 5 4。 发现7、6都须要OP,而从 5 開始须要进行OP了。那么答案就是全部<=5 的数了。

这样的算法须要能找到 2 1 6 3 7 5 4 中 递增序列6, 7. 复杂度是O(n^2),空间复杂度是O(1)。

2.2 时间:O(n) 空间:O(1)

8 6 5 7 9 5 4

目标:找到最大的数、第二大的数、第三大的数,且最大的数在最后。其它几位数依次在前面。比方

8 6 5 7 9 5 4 ->8 6 5 7 9 5 4

5 2 1 6 3 7 0 4 ->5 2 1 6 3 7 0 4

3 4 8 10 8 -> 3 4 8 10 8 (这样的情况下仅仅能是10,由于8出现2次,当中1次还在10后面,因此排除8)

当找到这个递增序列后,比方:5 2 1 6 3 7 0 4->5 2 1 6
3 7 0 4。

那么我知道4一定在5之后出现了,那么4一定要进行op操作,放到首位,仅仅要4放到了首位,那么其它的3,2,1,0等<=4的数,全都是要进行操作的。(3也要放到首位,那么2也要放到首位,那么...)。

能够看到仅仅有 5, 6, 7三个数不须要进行op操作。因此总的op数量是n-3 = 8 - 3 = 5.

为了找到这个序列,我打算:从右往左遍历,

idx: 为遍历的指针。p: 上述递增序列的最低位指针, _min: 记录arr[idx, p-1]之间的最大的值。在遍历过程中,不断地把递增序列移到右側,比方

idx: 6, p: 6,

8 6 5 7 9 5 4

_min: uninitialzed

idx: 5, p: 6,

8 6 5 7 9 5 4 [ 5比4大。因此交换 5和4的位置 ]

8 6 5 7 9 4 5

_min: 4 (_min更新为4)

idx: 4, p: 6

8 6 5 7 9 4 5  [ 9比5大,因此交换 9 和 5 的位置 ]

8 6 5 7 5 4 9

_min: 5 (更新为5和4中的最大者)

idx: 3, p: 6

8 6 5 7 5 4 9

8 6 5 4 5 7 9  [ 7 比 9 小。因此7能够纳入递增序列中: 交换4和7,p-- ]

_min: 5 (4,5中的最大者)

idx: 2, p: 5

8 6 5 4 5 7 9  [ 因为5 <= _min(5), 因此直接 idx--]

idx:1 , p: 5

8 6 5 4 5 7 9  [ 6大于_min,因此是ok,更新递增序列, swap(6, 5), p--]

8 5 5 4 6 7 9  [swap之后的结果]

idx: 0, p: 4

8 5 5 4 6 7 9 [ 8比_min大,8比6都大,因此p不断自增,知道8 < 9才停止,此时p指向了9,例如以下图]

8 5 5 4 6 7 9 [ 8 比 9 小,因此swap(8, 7)]

7 5 5 4 6 8 9 [结果]

idx: -1, p: 5

-> break;

因此最大递增序列是长度为2。{8, 9}。因此返回 n- 2 即 7 - 2 = 5

复杂度分析:

扫描的时间为 O(n)。

对于swap操作,最后的递增序列类似于一个栈,每一个元素最多进栈出栈一次,也是最多 O(n)。 因此时间复杂度是 O(n),空间复杂度是 O(1)。

3, 更优算法

这样的算法的时间复杂度是 O(n),空间复杂度是 O(1)。

详细思路:8
6 5 7 10
9 4。从左往右找到阶段性的山腰(8,10)。然后把之间的山谷和山背都去掉(6,5,7, 以及 9,4)

有p1, p2两个指针。p1指向8。p2指向6,比8小,然后右移。指向5,还是小于8。接着右移。最后指向了10,此时 p1也更新指向到10. 片

继续从9開始走。

p1指向过(8,10),p2指向过(6,5,7,9,4)p2中最大的是9,因此须要把 p1 指向过的(8,10)中比9小的排除掉就是最后的答案。排除的过程就是:p1,p2 再反复上面的过程,仅仅是如今须要记录 p1 所指向的元素中比 9大的数量是多少,这就是最后的答案。

上面这样的方法,写代码简单。可行。

时间空间复杂度也是能够的。

数组进行多少次OP操作,才干有序的更多相关文章

  1. 通过数组和枚举简化GPIO操作编码

    在工作中,经常遇到大量使用GPIO作为数字量输入输出来控制设备或采集状态,每次定义操作不同的GPIO针脚既麻烦又容易出错,于是就想要简化操作过程.对于数字量输入来说就是采集对应针脚的状态:而输出则是根 ...

  2. JavaScript面试技巧之数组的一些不low操作

    本文主要从应用来讲数组api的一些骚操作; 如一行代码扁平化n维数组.数组去重.求数组最大值.数组求和.js排序.对象和数组的转化等: 上面这些应用场景你可以用一行代码实现? 1.扁平化n维数组 1. ...

  3. 树状数组区间加法&区间求和操作

    树状数组区间加法&区间求和操作 一般的树状数组解决区间加&单点询问并不复杂 但是要解决区间求和... 我们假设原数组是\(\{a_i\}\),差分数组\(\{d_i=a_i-a_{i- ...

  4. redis:order set有序集合类型的操作(有序集合)

    1. order set有序集合类型的操作(有序集合) 有序集合是在无序集合的基础上加了一个排序的依据,这个排序依据叫score,因此声明一个集合为有序集合的时候要加上score(作为排序的依据) 1 ...

  5. 通过数组和枚举简化GPIO操作编码(转)

    源: 通过数组和枚举简化GPIO操作编码

  6. MongoDB .Net Driver(C#驱动) - 内嵌数组/嵌入文档的操作(增加、删除、修改、查询(Linq 分页))

    目录 一.前言 1. 运行环境 二.前期准备工作 1. 创建 MongoDBContext MongoDb操作上下文类 2.创建测试类 3.创建测试代码 三.内嵌数组增加元素操作 1.Update.S ...

  7. 谈谈Python中列表、元组和数组的区别和骚操作

    一.列表(List) 1.列表的特点 列表是以方括号“[]”包围的数据集合,不同成员以“,”分隔.如 L = [1,2,3], 列表a有3个成员. 列表是可变的数据类型[可进行增删改查],列表中可以包 ...

  8. PHP数组/Hash表的实现/操作、PHP变量内核实现、PHP常量内核实现 - [ PHP内核学习 ]

    catalogue . PHP Hash表 . PHP数组定义 . PHP变量实现 . PHP常量实现 1. PHP Hash表 0x1: 基本概念 哈希表在实践中使用的非常广泛,例如编译器通常会维护 ...

  9. [Effective JavaScript 笔记]第46条:使用数组而不要使用字典来存储有序集合

    对象属性无序性 js对象是一个无序属性集合. var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说.for...in循环,先输出哪个属性都有可能.获取和设置 ...

随机推荐

  1. wampserver配置多站点

    1.打开C:\wamp\bin\apache\apache2.2.22\conf\httpd.conf(因安装的路径而异),查找listen 80 下面加上listen 8080 2.然后加上 < ...

  2. 基于mkdocs-material搭建个人静态博客

    基于mkdocs-material搭建个人纯静态博客,没有php,没有mysql 如果你只是想安安静静的放一些技术文章,发布到个人站点或github-pages,mkdocs-material很适合你 ...

  3. AWS S3 对象存储服务

    虽然亚马逊云非常牛逼,虽然亚马逊云财大气粗,虽然亚马逊用的人也非常多,可是这个文档我简直无法接受,特别是客服,令人发指的回复速度,瞬间让人无语,可是毕竟牛逼.忍了,躺一次坑而已 1.图片上传 1.1 ...

  4. BZOJ 2140 Tarjan

    思路: 跟POJ有一道时限挺长的题一模一样  哦 POJ 1904 题解可以看这个(捂脸) http://blog.csdn.net/qq_31785871/article/details/52963 ...

  5. web前端处理订单待支付倒计时计算显示问题

    在商城类项目的时候,有很多待支付的订单,有时候在订单列表页面会分别显示倒计时,就是页面会有很多倒计时的订单. 处理方法: 1.调用后端接口拿到所有的订单,获取所有的倒计时订单,获取到期时间(尽量时间戳 ...

  6. css3动画简单案例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. PowerDesigner 逆向工程Non SQL Error : Could not load class com.mysql.jdbc.Driver

    建立与数据库的连接. 在菜单条上,有一个Database的选择项: 选择connect…后弹出设置对话框: 在Data source里选择第三个单选按钮,即Connection profile:后,点 ...

  8. 【Oracle】glogin.sql脚本模板

    [root@localhost ~]# su - oracle [oracle@localhost ~]$ vi $ORACLE_HOME/sqlplus/admin/glogin.sql defin ...

  9. [转] 利用git钩子,使用python语言获取提交的文件列表

    项目有个需求,需要获取push到远程版本库的文件列表,并对文件进行特定分析.很自然的想到,要利用git钩子来触发一个脚本,实现获取文件列表的功能.比较着急使用该功能,就用python配合一些git命令 ...

  10. 软件开发的MVC构架

    MVC:IDE开发环境开发时,无意中使用的软件结构. 转自于wikipedia:http://zh.wikipedia.org/wiki/MVC 软件的层次划分:框架--组件(设计模式)--算法与数据 ...