【学习笔记】一类比较问题

本文介绍3类比较问题

1、逆序对

问题:一列数7 3 2 1 6 8 4 5,每次操作可以任选两个相邻的数交换,问最少几次操作使得数列升序?

答案等于数列逆序对数

定义逆序对:一列数{a}中对于 i < j , a i > a j i<j,a_i>a_j i<j,ai>aj,称 ( a i , a j ) (a_i,a_j) (ai,aj)为一个逆序对

简要证明:
假如我现在是一个人工智能,我的目标使得操作数最小。
每次操作肯定是做收益最高的。
每次操作我都可以令数列的逆序对数-1

因为一列数不是有序的,必定存在相邻的两个数 a i > a i + 1 a_i>a_{i+1} ai>ai+1
然后我交换他们
整个数列是 a 1 , a 2 , . . . , a i , a i + 1 , . . . , a n − 1 , a n a_1,a_2,...,a_i,a_{i+1},...,a_{n-1},a_n a1,a2,...,ai,ai+1,...,an1,an
交换之后 a i , a i + 1 a_i,a_{i+1} ai,ai+1之外的逆序对不会受到影响,只会使得 a i , a i + 1 a_i,a_{i+1} ai,ai+1这一对逆序对消失,所以一次操作使得数列逆序对数-1

然后最终升序的数列逆序对数为0,所以答案等于逆序对数

拓展:
若一列数有重复的数,结论是否成立?成立。

2、环

问题:一列数7 3 2 1 6 8 4 5,每次操作可以任选两个数交换,问最少几次操作使得数列升序?

前提:数互不相同。
对于每一个数,它在最终数列里位置一定是确定的。
对于最终数列的每一个位置,他最终只能放一个确定的数。
7 3 2 1 6 8 4 5
1 2 3 4 5 6 7 8
对于每个数往他的目标位置连一条有向边表示最终要到那里去。
在这里插入图片描述
发现数列里的数会构成至少一个环,每个数都会在某一个环里
我们交换两个数,一定会交换两个在同一个环里的数
对于一个环,环里有 x ( x > = 1 ) x(x>=1) x(x>=1)个数,一定是用 x − 1 x-1 x1次操作使得这个环变有序

所以结论就是,这列数如果能构成 k ( k > = 1 ) k(k>=1) k(k>=1)个环,答案是 n − k n-k nk

3、决策树

重头戏。

对于一个有5个未知大小的数的数列,最少需要几次比较才能保证数列有序?

先算3个数的数列
第一步,可以 a < b a<b a<b
第二步,若 b < c b<c b<c,完成;若 c < b c<b c<b,则还要第三步比较 a , c a,c a,c的大小
答案为3

4个数的数列
先用3步确定3个数的大小关系 a < b < c a<b<c a<b<c
d d d b b b比较,假设 d < b d<b d<b,再把 d d d a a a比较,共用5步

上述也证明了一个引理:2次比较可以将一个数插入到有3个数的有序数列中

回到原问题。
设a,b,c,d,e
先用两次 a < b , c < d , e a<b,c<d,e a<b,c<d,e
比较 b , d 。 设 b < d b,d。设b<d b,db<d,那么 a < b < d , c < d a<b<d,c<d a<b<d,c<d
再用2次可以将 e e e插到 a < b < d a<b<d a<b<d
目前共用5次,知道了 a , b , d , e a,b,d,e a,b,d,e之间的关系,且 c < d c<d c<d
假设 a < b < e < d , c < d a<b<e<d,c<d a<b<e<dc<d这是最劣的情况,再用2次比较可以把 c c c放到 a < b < e a<b<e a<b<e当中去

共用7次,解决问题。

推广:决策树。
定义:决策树,每个决策可能引出两个或多个事件,导致不同的结果,把这种决策分支画成图形像一棵树,称决策树。

对于我们这个问题,当前的数之间的大小关系是一个状态,一个比较比如会出现 a < b 或 a > b a<b或a>b a<ba>b,引申出2个不同的新状态
所以进行 k k k次操作,会有 2 k 2^k 2k中状态之中确定一种
5个数的大小关系有 5 ! = 120 5!=120 5!=120中可能,对应 2 7 = 128 > 120 , 2 6 = 64 < 120 2^7=128>120,2^6=64<120 27=128>120,26=64<120
6次比较无法确定一个5个数的数列的顺序,7次就可以。

推广到 n n n个数的数列。
至少比较多少次是的数列有序?
根据决策树,至少比较 ⌊ l o g 2 n ! ⌋ \lfloor{log_2^{n!}}\rfloor log2n!
然而可以发现决策树并不完全正确,一次比较并不一定有效,延伸出来的两个状态并不一定不同
但是我们可以通过决策树确定比较次数的下界为 ⌊ l o g 2 n ! ⌋ \lfloor{log_2^{n!}}\rfloor log2n!约等于 ⌊ n l o g 2 n ⌋ − n \lfloor{nlog_2^n}\rfloor-n nlog2nn
这是一个未被证明,也未被证伪的结论,参考于Donald E. Knuth先生的The Art of Computer Programming

但是从算法角度上来说,我们可以得知,对一列 n n n个数的数列进行基于比较的排序,时间复杂度为 O ( n l o g 2 n ) O(nlog_2^n) O(nlog2n)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值