Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.git
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).github
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,1markdown
本題考查字典序排列:
把升序的排列(固然,也能夠實現爲降序)做爲當前排列開始,而後依次計算當前排列的下一個字典序排列。
算法思想:
對當前排列從後向前掃描,找到一對爲升序的相鄰元素,記爲i和j(i < j)。若是不存在這樣一對爲升序的相鄰元素,則全部排列均已找到,算法結束;不然,從新對當前排列從後向前掃描,找到第一個大於i的元素k,交換i和k,而後對從j開始到結束的子序列反轉,則此時獲得的新排列就爲下一個字典序排列。這種方式實現獲得的全部排列是按字典序有序的,這也是C++ STL算法next_permutation的思想。測試
class Solution {
public:
//尋找整數序列num的下一個全排序列
void nextPermutation(vector<int> &num) {
if (num.size() < 2) return;
int i, k;
for (i = num.size() - 2; i >= 0; --i)
if (num[i] < num[i + 1])
break;
//若不存在子升序,則說明當前排列是最大排列,此時i = -1,下一排列便是最小排列,翻轉整個序列便可
if (i < 0)
{
reverse(num.begin() , num.end());
return;
}
//找到了子升序
for (k = num.size() - 1; i >= 0 && k > i ; --k)
if (num[i] < num[k])
break;
if (i >= 0)
{
swap(num[i], num[k]);
reverse(num.begin() + i + 1, num.end());
return;
}
}
};