[leetcode]Next Permutation
下一个组合数。因为有数组内一部分的排序,c++更自然些。算法很简单,从末尾向开头找不合顺序的,然后调换,然后把后面的排序。调换要找到那个刚好比pivot大的元素,因为再小的,如果换过去,这些顺序已经排过了。
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
void nextPermutation(vector<int> &num) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int idx = num.size() - 1;
bool inorder = true;
while ( idx > 0) {
if ((num[idx] > num[idx-1])) {
inorder = false;
break;
}
idx--;
}
if (inorder) {
sort(num.begin(), num.end());
return;
}
idx--;
// idx is the number need to be exchanged
int minIdx = INT_MAX;
for (int i = idx+1; i < num.size(); i++) {
if (num[i] > num[idx]) {
if (minIdx == INT_MAX || num[i] < num[minIdx])
{
minIdx = i;
}
}
}
swap(num, idx, minIdx);
sort(num.begin() + idx + 1, num.end());
}
void swap(vector<int> &num, int a, int b) {
int tmp = num[a];
num[a] = num[b];
num[b] = tmp;
}
};
第二遍:之前的方法里面用了sort,其实不算是O(n)的。C++库里面的方法是用reverse,原因是swap之后,后半部分其实正好倒序,这样reverse就相当于sort了。如果用sort,Annie的写法更简洁。https://github.com/AnnieKim/LeetCode/blob/master/NextPermutation.h
class Solution {
public:
void nextPermutation(vector<int> &num) {
int i = num.size() - 1;
while (i > 0 && num[i] <= num[i-1])
i--;
if (i == 0)
{
reverse(num, 0, num.size()-1);
return;
}
int pivot = num[i-1];
int idx = -1;
for (int j = num.size()-1; j >= i; j--)
{
if (idx == -1 && num[j] > pivot)
{
idx = j;
}
else if (idx != -1 && num[j] > pivot && num[j] < num[idx])
{
idx = j;
}
}
swap(num, i-1, idx);
reverse(num, i, num.size()-1);
}
void reverse(vector<int> &num, int l, int r)
{
while (l < r)
{
swap(num, l, r);
l++;
r--;
}
}
void swap(vector<int> &num, int i, int j)
{
int tmp = num[i];
num[i] = num[j];
num[j] = tmp;
}
};

浙公网安备 33010602011771号