题目:
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,23,2,1 → 1,2,31,1,5 → 1,5,1
将当前permutation看作是一个整数,如将“1,2,3”看作123,则next permutation是由“1,2,3”所组成的最小的比“123”大的数,即“132”。如果当前permutation已为最大数,如"321",则其next permutation为起始的最小数,即"123"。
题解:
<span style="color:#000000;">class Solution {
public:
void nextPermutation(vector<int> &num) {
if(num.size() <= 1)
return;
vector<int>::iterator i = num.end();
i = i - 2;
while(true)
{
vector<int>::iterator j = i + 1;
if(*i < *j)
{
vector<int>::iterator k = num.end();
while(!(*i < *--k));
iter_swap(i, k);
reverse(j, num.end());
return;
}
if( i == num.begin() )
{
reverse(num.begin(), num.end());
return;
}
i--;
}
}
};</span>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char* argv[])
{
Solution s;
int iArray[] = {1,2};
size_t count = sizeof(iArray)/sizeof(int);
vector<int> test(iArray, iArray+count);
s.nextPermutation(test);
return 0;
}
一年后再做。思路:规律是,从后往前找第一个升序对,如果升序对不存在,说明当前为最大值,rotate整个permutation后得到最小值。否则,存在升序对,则将升序对中小的数与 再次从后往前找的第一个比该数大的数交换,交换后将该数后的partial permutation做rotation。
自己造轮子的做法:
class Solution {
public:
void nextPermutation(vector<int> &num) {
if(!num.size())
return;
int i = num.size()-2;
while(i >= 0) {
if(num[i] < num[i+1])
break;
i--;
}
if(i < 0) {
rotate(num, 0, num.size()-1);
} else {
int k = num.size()-1;
while(k > i) {
if(num[k] > num[i]) {
int temp = num[i];
num[i] = num[k];
num[k] = temp;
break;
}
k--;
}
rotate(num, i+1, num.size()-1);
}
}
void rotate(vector<int> &num, int start, int end) {
while(start <= end) {
int temp = num[start];
num[start] = num[end];
num[end] = temp;
start++;end--;
}
}
};
class Solution {
public:
void nextPermutation(vector<int> &num) {
if(!num.size())
return;
auto i = num.end() - 2;
while(i >= num.begin())
{
auto j = i + 1;
if(*i < *j)
{
auto k = num.end()-1;
while(*k <= *i)
k--;
iter_swap(i, k);
reverse(j, num.end());
return;
}
i--;
}
reverse(num.begin(), num.end());
}
};
public class Solution {
public void nextPermutation(int[] num) {
if(num.length <= 1)
return;
int i = num.length - 2;
while(i >= 0) {
if(num[i] < num[i+1])
break;
i--;
}
if( i >= 0 ) {
int j = num.length - 1;
while(num[j] <= num[i])
j--;
int temp = num[i];
num[i] = num[j];
num[j] = temp;
rotate(num, i+1, num.length-1);
return;
}
rotate(num, 0, num.length-1);
}
public void rotate(int[] num, int start, int end) {
while(start <= end) {
int temp = num[start];
num[start] = num[end];
num[end] = temp;
start++;end--;
}
}
}
class Solution:
# @param num, a list of integer
# @return a list of integer
def nextPermutation(self, num):
if len(num) <= 1:
return num
i = len(num) - 2
while i >= 0:
if num[i] < num[i+1]:
break
i -= 1
if i >= 0:
j = len(num) - 1
while num[j] <= num[i]:
j -= 1
temp = num[j]
num[j] = num[i]
num[i] = temp
self.rotate(num, i+1, len(num)-1)
return num
self.rotate(num, 0, len(num)-1)
return num
def rotate(self, num, start, end):
while start <= end:
temp = num[start]
num[start] = num[end]
num[end] = temp
start += 1
end -= 1