【经典算法】STL之next_permutation和prev_permutation
来源:互联网 发布:南望王师又一年 知乎 编辑:程序博客网 时间:2024/05/17 01:07
next_permutation和prev_permutation这两个算法的实现,非常的经典,同样十分的有趣。
第一次听说大约是在大四的时候,听一个准备面试的学长说起。
今天又遇到同事正好问了面试的同学这个问题,遂记录下来。
首先,来弄明白什么是"下一个"排列,或者"上一个"排列。
举个例子,abc组成的一个排列,以字典序来说,abc,acb,bac,bca,cab,cba,一共是六种。
这样abc最小,cba最大。比如说到bac,下一个排列就是bca,上一个排列acb。
先来看看next_permutation
(1)如果采用直接枚举所有的排列,然后找出下一个排列,显得有点笨拙。
但凡说起算法,自然会有巧妙的解法。为此,又仔细去翻看侯捷先生的经典著作《STL源码剖析》。
基本思路:从最末尾向前面找两个相邻的元素i和j,并且满足i<j。然后从最末尾继续向前找第一个大于i的元素k,
将i和k交换,并将j之后的元素颠倒得到的序列即为所求。
描述有点抽象,还是来点形象的。
1743256------->1743265
这里i=5,j=6,第一个比大于i的是k=6。
175432------->275431----->271345
这里i=1,j=7,第一个比大于i的元素k=2。
为什么是这样的?
我们来看下面一个事实
令F为i之前的数,E为j之后小于j的数,E必定为一个从大到小的全排列(形如54321这种,如若不然,必定存在一组数,使得左边小于右边,如53421),
则原来的数FijE。
存在这样的事实,ijE组成的序列中一定存在新的排列比ijE大,因为至少jiE这个数是满足的。
这时从上面FijE最末端寻找一个数k,使得它第一个大于i,这个数可以是j。
1>这里若E中的数均小于i,则k为j,那么显然交换i和E中的某个数,这个新组成的数值小于ijE。
那么只能交换i和j。这时新组成的数jiE,一定大于ijE。因为ji>ij,所以新组成的数jiE,固定前两位ji,找到E中数的最小排列,则是直接将E颠倒即可。
这是因为E是一个从大到小的全排列。
2>这里若E中存在某个数大于i,则将这个数记为k,于是将E记为SkT,S为k之前的数的排列(大于i),T为k之后的数的排列(不大于i)。
k是从最末尾比较,第一个比i大的数。与i交换的数中,k肯定是E中满足大于i最小的那一个。于是,交换之后kj>ij,然后固定kj,求SiT构成的序列的最小排列。
由前述(1)中同理,颠掉SiT,即可。
好了,到这里基本就知道next_permutation的计算方式了。
(2)prev_permutation
知道了next_permutation怎么求,prev_permutation就比较简单了。
基本思路:
从最末尾向前面找两个相邻的元素i和j,并且满足i>j。然后从最末尾继续向前找第一个小于i的元素k,
将i和k交换,并将j之后的元素颠倒得到的序列即为所求。
- 【经典算法】STL之next_permutation和prev_permutation
- STL经典算法集锦<六>之排列(next_permutation/prev_permutation)
- STL经典算法集锦之排列(next_permutation/prev_permutation
- STL算法之 next_permutation、prev_permutation 的原理和实现
- STL源码学习----next_permutation和prev_permutation算法
- STL全排列算法next_permutation和prev_permutation
- STL算法:prev_permutation和next_permutation的使用
- STL算法:prev_permutation和next_permutation的使用
- STL具体操作之next_permutation和prev_permutation函数
- STL之next_permutation和prev_permutation函数
- stl中的next_permutation和prev_permutation
- STL/next_permutation()和prev_permutation()函数
- 【STL源码剖析读书笔记】【第6章】算法之next_permutation和prev_permutation算法
- [转载]STL算法:prev_permutation和next_permutation的使用
- STL algorithm算法next_permutation,prev_permutation(39)
- STL源码剖析之next_permutation,prev_permutation
- STL之生成全排列:next_permutation & prev_permutation
- STL prev_permutation&next_permutation
- hdu2647 Reward
- [LeedCode OJ]#234 Palindrome Linked List
- 选择排序之堆排序
- 十道海量数据处理题
- UVA 816 有点绕的迷宫
- 【经典算法】STL之next_permutation和prev_permutation
- 算法系列-合并有序数组
- 数组中只出现一次的数字
- Nginx基础. 开发HTTP过滤模块
- cannot do a partial commit during a merge
- IOS_UITableViewController 视图控制器的生命周期
- 浅谈面向对象
- 标准C++中的string类的用法詳解
- 配置ssh免密码登录