# 算法题丨Next Permutation

### 描述

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


### 算法分析

a1: 1,2,3;　　a2: 1,3,2;　　a3: 2,1,3;　　a4: 2,3,1;　　a5: 3,1,2;　　a6: 3,2,1;

/** Tips: next permuation based on the ascending order sort
* sketch :
* current: 1   5  8  4  7  6  5  3  1
*                    |        |     |
*          find i----+        j     +----end
* swap i and j :
*          1   5  8  5  7  6  4  3  1
*                    |        |     |
*               j----+        i     +----end
* reverse j+1 to end :
*          1   5  8  5  1  3  4  6  7
*                    |              |
*          find j----+              +----end
* */


a）从后向前查找第一个相邻元素对(i,i+1)，并且满足A[i] < A[i+1]。

b）在[i+1,end)中寻找一个最小的j使其满足A[i]<A[j]。

c）将i与j交换。

d）逆置[j,end)

### 代码示例(C#)

public void NextPermutation(int[] nums)
{
int i = nums.Length - 2;
//末尾向前查找，找到第一个i，使得A[i] < A[i+1]
while (i >= 0 && nums[i + 1] <= nums[i])
{
i--;
}
if (i >= 0)
{
//从i下标向后找第一个j,使得A[i]<A[j]
int j = nums.Length - 1;
while (j >= 0 && nums[j] <= nums[i])
{
j--;
}
//交换i，j
Swap(nums, i, j);
}
//逆置j之后的元素
Reverse(nums, i + 1, nums.Length);
}

//逆置排序
private void Reverse(int[] nums, int start, int end)
{
int i = start, j = end - 1;
while (i < j)
{
Swap(nums, i, j);
i++;
j--;
}
}

//交换
private void Swap(int[] nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}


• 时间复杂度O (n).
• 空间复杂度O (1).

### 附录

posted @ 2018-04-17 17:30  Lancel0t  阅读(...)  评论(...编辑  收藏