Next Permutation
Total Accepted: 4075 Total Submissions: 16219 My Submissions
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
这个应该是基础。在C/C++中有封装好的方法可以使用。
其实基本思路应该是这样的。
1、从尾到头寻找第一个相邻的,下降的两个数。如果是出现这种情况,说明还可以找到下一个序列。假设找到的位置是first。
2、根据1,我们可以知道,从尾到first+1,这个序列应该是上升的。从中找到第一个比num[first]大的数,然后和first交换位置。
3、从first+1到len-1进行排序,这样就完成了一次查找过程。
举个例子来说吧。
假设原始序列为[10,12,14,16,17],
查找下一个排列的过程如下:
1、从右到左找到第一个连续下降的两个数。
此时first为3。
2、从右到first+1找到第一个比它大的数,然后两个数交换。
然后对first+1之后的序列逆序,即为结果。逆序的原因是,因为每次查找的都是从右到左第一个比frist大的数,所以交换以后,first后面的序列一定是从右到左上升的。逆序以后才为最小序列。
4、下一次查找的逻辑和之前相同
5、从右到左查找第一个比first大的数,然后交换。
6、对first+1后面的序列逆序。
依次重复上述步骤,就可以得到所有的全排列。注意如果从右到左找不到下降的序列,则说明目前数据已全部有序,排序规则为从大到小,那么下一个全排列就是将当前数组逆序。
本题只要求求一个,所以一个步骤就可以了。
Java AC
public class Next_Permutation {
public void nextPermutation(int[] num) {
if (num == null || num.length == 0) {
return;
}
int len = num.length;
int first = getFirst(num);
if (first == -1) {
reverse(num, 0, len - 1);
} else {
int i = len - 1;
for (; i > first; i--) {
if (num[i] > num[first]) {
break;
}
}
swap(num, first, i);
reverse(num, first + 1, len - 1);
}
}
public int getFirst(int[] num) {
int len = num.length;
for (int i = len - 2; i >= 0; i--) {
if (num[i] < num[i + 1]) {
return i;
}
}
return -1;
}
public void swap(int[] num, int i, int j) {
int tmp = num[i];
num[i] = num[j];
num[j] = tmp;
}
public void reverse(int[] num, int low, int high) {
while (low < high) {
swap(num, low, high);
low++;
high--;
}
}
}
Python AC
class Solution:
# @param num, a list of integer
# @return a list of integer
def nextPermutation(self, num):
nLen = len(num)
first = -1
for i in xrange(nLen - 2, -1, -1):
if num[i] < num[i + 1]:
first = i
break
if first == -1:
num.sort()
return num
else:
for i in xrange(nLen - 1, first, -1):
if num[i] > num[first]:
num[i], num[first] = num[first], num[i]
break
low = first + 1
high = nLen - 1
while low < high:
num[low], num[high] = num[high], num[low]
low += 1
high -= 1
return num