字典序与next_permutation

求字典序的直观方法就是从后往前不断操作,让一个串越来越大,next_permutation中给出了求字典序的方法,这个方法是:

1、如果串是完全逆序的,它不能再大了(但仍把它反转,使其成为最小串)。2、如果串没有完全逆序,它就还能变大,怎么变大呢?如果最后两个元素是顺序的,把它们逆序这个串就变大了;如果最后两个元素是逆序的,那么串的尾部就有一个逆序子串,把这个逆序子串做某操作就可以。什么是“某操作”呢?

因为子串是逆序的,从后往前它会变得越来越大的,这样子串很高兴,但既然整个串不是完全逆序,那从后往前子串就会遇到一个小的数x,这样就不能再继续变大了。子串很生气,它要教训x,因为x是个小数,逆序列中就有一个成员可以和x交换同时保证整个子列仍是逆序的,这个成员就是子列中第一个比x大的数y,这样y强迫x与它交换位置。交换之后我们看整个串一定是变大了,因为x位置的那个数变大了。交换之后子串很高兴,它翻了个身,变成顺序的了。既然变成顺序的,那光看子串的话,子串一定是变小了,同时整个串变大了(变大的幅度尽量小,在子串大的过x的成员中,y就最小)。这就是“某操作”。

这样我们写一个next_permutation

void nextPermutation(vector<int> &v){
  if(v.size()<=1)return ;
  //more than two numbers
  int i,j,k;
  for(i=v.size()-1; i>=0;--i)
    if(v[i]>v[i-1])   break;
  //if(i==0) v is sorted already
  if(i==0){
    reverse(v.begin(),v.end());
    return; }
  // v is not sorted,
  for(j=v.size()-1; j>=i; --j)
    if(v[j]>v[i-1])   break;
  swap(v[i-1],v[j]);
  reverse(v.begin()+i,v.end());
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值