Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

  

class Solution {
public:
void reverse(int begin, int end , vector<int> &num)
{
assert(begin >= && begin <= end && end < num.size()); int i = begin , j = end;
while(i<j)
{
int temp = num[i];
num[i] = num[j];
num[j] = temp;
i++;
j--;
}
}
void nextPermutation(vector<int> &num) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int len = num.size();
if(len < ) return ;
int i, j;
for( i = len - ; i>= ; i-- )
if(num[i] >= num[i+])
continue;
else
break; if(i>=)
{
j = len -;
while(j >= && num[j] <= num[i])j--; int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
reverse(i+, len-, num);
}
};

reference :

http://stackoverflow.com/questions/11483060/stdnext-permutation-implementation-explanation

http://yucoding.blogspot.com/2013/04/leetcode-question-61-next-permutation.html

http://fisherlei.blogspot.com/2012/12/leetcode-next-permutation.html

一个很好的解释,来字stackoverflow

Let's look at some permutations:

...
How do we go from one permutation to the next? Firstly, let's look at things a little differently. We can view the elements as digits and the permutations as numbers. Viewing the problem in this way we want to order the permutations/numbers in "ascending" order. When we order numbers we want to "increase them by the smallest amount". For example when counting we don't count 1, 2, 3, 10, ... because there are still 4, 5, ... in between and although 10 is larger that 3, there are missing numbers which can be gotten by increasing 3 by a smaller amount. In the example above we see that 1 stays as the first number for a long time as there are many reorderings of the last 3 "digits" which "increase" the permutation by a smaller amount. So when do we finally "use" the ? When there are only no more permutations of the last digits.
And when are there no more permutations of the last digits? When the last digits are in descending order. Aha! This is key to understanding the algorithm. We only change the position of a "digit" when everything to the right is in descending order because if it isn't in descending order then there are still more permutations to go (ie we can "increase" the permutation by a smaller amount). Let's now go back to the code: while (true)
{
It j = i;
--i; if (*i < *j)
{ // ...
} if (i == begin)
{ // ...
}
}
From the first lines in the loop j is an element and i is the element before it.
Then if the elements are in ascending order (if (*i < *j)) do something.
Otherwise if the whole thing is in descending order (if (i == begin)) then this is the last permutation.
Otherwise we continue and we see that j and i are essentially decremented. We now understand the if (i == begin) part so all we need to understand is the if (*i < *j) part. Also note: "Then if the elements are in ascending order ..." which supports out previous observation that we only need to do something to a digit "when everything to the right is in descending order". The ascending order if statement is essentially finding the leftmost place where "everything to the right is in descending order". Let's look again at some examples: ... ... ...
We see that when everything to the right of a digit is in descending order, we find the next largest digit and put it in front and then put the remaining digits in ascending order. Let's look at the code: It k = end; while (!(*i < *--k))
/* pass */; iter_swap(i, k);
reverse(j, end);
return true;
Well since the things to the right are in descending order, to find the "next largest digit" we just have to iterate from the end which we see in the first lines of code. Next we swap the "next largest digit" to the front with the iter_swap() statement and then since we know that that digit was the next largest, we know that the digits to the right are still in descending order so to put it in ascending order we just have to reverse() it.

LeetCode_Next Permutation的更多相关文章

  1. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  2. [LeetCode] Palindrome Permutation II 回文全排列之二

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  3. [LeetCode] Palindrome Permutation 回文全排列

    Given a string, determine if a permutation of the string could form a palindrome. For example," ...

  4. [LeetCode] Permutation Sequence 序列排序

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  5. [LeetCode] Next Permutation 下一个排列

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  6. Leetcode 60. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  7. UVA11525 Permutation[康托展开 树状数组求第k小值]

    UVA - 11525 Permutation 题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个 学了好多知识 1.康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+ ...

  8. Permutation test: p, CI, CI of P 置换检验相关统计量的计算

    For research purpose, I've read a lot materials on permutation test issue. Here is a summary. Should ...

  9. Permutation

    (M) Permutations (M) Permutations II (M) Permutation Sequence (M) Palindrome Permutation II

随机推荐

  1. #ifdef __cplusplus extern "C" {代码} 倒底是什么意思?

    时常在cpp的代码之中看到这样的代码: #ifdef __cplusplus   extern "C" { #endif //一段代码 #ifdef __cplusplus } # ...

  2. logstash 发送zabbix告警

    <pre name="code" class="html">[elk@dr-mysql01 test]$ cat t1.conf input { s ...

  3. 了解 Windows Azure 存储的可伸缩性、可用性、持久性和计费

    借助 Windows Azure存储,应用程序开发者及其应用程序和用户可以在云中使用可用性更高.持久性更长.可伸缩性更强的海量存储.开发者可以构建能随时随地高效访问数据的服务,在所需的时间段内存储任意 ...

  4. 利用Visual Studio寻找C#程序必要的运行库文件

    在工程打包中,有时候很头痛的就是运行所需要的库文件不能够全面的包含进来,特别是有时候调用了一系列外部扩展.对于这些问题,我们可以借用Visual Studio的打包功能帮助我们寻找软件运行必须的库文件 ...

  5. 迅雷API:实现文件下载

     今天到迅雷公司的SDK文档网站上逛了逛,竟然发现它们已经提供了完备的API接口,我心中不禁大喜,但是SDK资料中的原版开发文件已经很难找到了,幸运的是我在github上搜索到了所需的文件,在这里我已 ...

  6. hdu3849-By Recognizing These Guys, We Find Social Networks Useful:双连通分量

    By Recognizing These Guys, We Find Social Networks Useful Time Limit: 2000/1000 MS (Java/Others)     ...

  7. eucMenu

  8. Linux文件io--one简述

    什么是文件IO IO就是input/output,输入/输出.文件IO的意思就是读写文件. 文件操作的主要接口API 什么是操作系统API (1)API是一些函数,这些函数是由linux系统提供支持的 ...

  9. AngularJs学习笔记3——自定义指令

    指令 概述: 前面也说过一些常用指令,用于快速入门.现在详细总结一下:指令用于实现各种页面的操作,是对于底层DOM操作的封装,扩展了HTML的行为,实现页面交互以及数据绑定. 指令是一种执行的信号,一 ...

  10. MyEclipse默认编码为GBK,修改为UTF8的方法

    MyEclipse 默认编码居然是GBK,js文件默认编码是ISO-....怎么可以这样呢? 都修改成UTF8的方法: 1.windows->Preferences...打开"首选项& ...