C++ next_permutation


算法流程如下:

Example 6 8 7 4 3 2

step 1      6 8 7 4 3 2

step 2      6 8 7 4 3 2

step 3      7 8 6 4 3 2

step 4      7 8 6 4 3 2

                 7 2 3 4 6 8

1、从右向左找到第一个非递增元素,即6

2、从右向左找到第一个大于6的元素,即7

3、将6与7置换

4、将6后的元素反转


next_permutation函数实现:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class Solution {  
  2. public:  
  3.     void nextPermutation(vector<int> &num) {  
  4.         _next_permutation(begin(num), end(num));    
  5.     }  
  6.     template<typename BidirIt>  
  7.     bool _next_permutation(BidirIt first, BidirIt last)  
  8.     {  
  9.         const auto rfirst = reverse_iterator<BidirIt>(last);  
  10.         const auto rlast = reverse_iterator<BidirIt>(first);  
  11.           
  12.         auto pivot = next(rfirst);  
  13.           
  14.         while(pivot != rlast && *pivot >= *prev(pivot))//step1  
  15.             ++pivot;  
  16.           
  17.         if(pivot == rlast){  
  18.             reverse(rfirst,rlast);  
  19.             return false;  
  20.         }  
  21.           
  22.         auto change = find_if(rfirst,pivot,bind2nd(greater<int>(),*pivot));//step2  
  23.           
  24.         swap(*change,*pivot);//step3  
  25.         reverse(rfirst,pivot);//step4  
  26.           
  27.         return true;  
  28.     }  
  29. };  


另一种实现:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. template<class BidirIt>  
  2. bool next_permutation(BidirIt first, BidirIt last)  
  3. {  
  4.     if (first == last) return false;  
  5.     BidirIt i = last;  
  6.     if (first == --i) return false;  
  7.    
  8.     while (1) {  
  9.         BidirIt i1, i2;  
  10.    
  11.         i1 = i;  
  12.         if (*--i < *i1) {//step1  
  13.             i2 = last;  
  14.             while (!(*i < *--i2));//step2  
  15.               
  16.             std::iter_swap(i, i2);//step3  
  17.             std::reverse(i1, last);//step4  
  18.             return true;  
  19.         }  
  20.         if (i == first) {  
  21.             std::reverse(first, last);  
  22.             return false;  
  23.         }  
  24.     }  
  25. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值