31. Next Permutation

来源:互联网 发布:有个卖时间的软件 编辑:程序博客网 时间:2024/06/06 09:41

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

题目翻译:实现下一个排列,把数组重新排列成字典序中下一个更大的数字排列,如果找不到这样的排列,那么必须把它重新排列成可能的最低顺序(以升序排列),必须在原处替换,不能占用额外内存。下面是一些例子,输入在左边栏,相应的输出在右边栏。

好了,题目看完了,确实很懵==所以参考了其他的博客,原来这里的字典序是指全排列中的顺序,例如:

1,2,3

1,3,2

2,1,3

2,3,1

3,1,2

3,2,1

       这里1,2,3的下一个更大的数字排列是1,3,2,而1,3,2的下一个更大的数字排列是2,1,3...以此类推,所以,怎么寻找那些很长的数组的下一个更大的数字排列呢?

       沿用参考的博客中的例子:如果给定的nums是 6,5,4,8,7,5,1,因为它的子序列8,7,5,1是已经按降序排列好的,调换这里的任意一个数字都不可能使排列更大,所以从后往前搜索一直到4这个数字,这时4,8,7,5,1已经不是降序排列的子数组了,并且4<5,如果能将4和5调换,那么整体数组变成6,5,5,8,7,4,1,这个时候的排列的确比nums要大,但是不满足题目中的next greater这个条件,我们要找的是它的下一个更大的排列,所以在调换了4和这5之后,需要把子数组8,7,4,1按照升序排列,nums变为6,5,5,1,4,7,8,这个数组就是我们要找的下一个更大的数字排列组合了。

代码中设置了标志位,如果数组中存在数字调换的情况,则把标志位设为1,并且假设调换的数字索引为i,对i+1-len(数组长度)之间的数字排序即可。如果标志位没变化,说明整个数组是按降序排列的,把整个数组重新排序即可。

                int flag=0;        int len = nums.length;if(len==0){return;}for(int i=len-2;i>=0;i--){int m = nums[i];for(int j=len-1;j>i;j--){//如果从后往前遍历时找到了比nums[i]大的数字,就交换这两个数字if(m<nums[j]){nums[i] = nums[j];nums[j] = m;flag=1;break;}}if(flag==1){//sort的使用(数组名,排序起点,排序终点),(PS:只对i+1和len之间的数字排序,不包括下标为len的)Arrays.sort(nums, i+1,len);//排序完成后,跳出整个循环break;    }}//如果整个数组遍历完,flag没有变化,说明整个数组是降序排列的,要把它变为升序if(flag==0){Arrays.sort(nums);}

参考的博客链接:

博客链接1

博客链接2

原创粉丝点击