一、环境说明
- 本文是 LeetCode 31题 : 下一个排列,使用c语言实现。
- 重在排列性质。
- 测试环境:Visual Studio 2019。
二、代码展示
void swap(int *a,int *b){
int temp = *a;
*a = *b;
*b = temp;
}
void reverse(int nums[],int left,int right){
while(left<right){
swap(nums+left,nums+right);
left++,right--;
}
}
void nextPermutation(int* nums, int numsSize){
int i = numsSize - 2;
while(i>-1&&nums[i]>=nums[i+1]){
i--;
}
int j = numsSize -1;
if(i>-1){
while(j>-1&&nums[i]>=nums[j]){
j--;
}
swap(nums+i,nums+j);
}
reverse(nums,i+1,numsSize-1);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
三、思路分析
- 下一个排列,字典序更大。如果组成整数,下一个排列,是第一个数值大于当前排列的排列。
- 所以我们的目的具现为:找到第一个数值大于当前排列的排列。
- 为了找到上述排列。我们需要:
- 从右往左遍历,当前位置是
i
i
i。
- 当
n
u
m
s
[
i
]
<
n
u
m
s
[
i
+
1
]
nums[i]nums[i]<nums[i+1],选定
n
u
m
s
+
i
nums+i
nums+i作为需要被交换的数。这一步确保
n
u
m
s
[
i
]
nums[i]
nums[i]右侧是一个降序序列。
- 再次从右往左遍历
n
u
m
s
nums
nums,当前位置是
j
j
j,当
n
u
m
s
[
j
]
>
n
u
m
s
[
i
]
nums[j]>nums[i]
nums[j]>nums[i],选取
n
u
m
s
+
j
nums+j
nums+j作为被交换的第二个数。
- 由于
2
2
2的操作,
n
u
m
s
[
i
]
nums[i]
nums[i]右侧的排列,是右侧的最大排列。反转
n
u
m
s
[
i
]
nums[i]
nums[i]右边所有数字,得到
n
u
m
s
[
i
]
nums[i]
nums[i]右侧的最小排列。
四、代码分析
- 理解思路很重要!
- 欢迎读者在评论区留言,作为日更博主,看到就会回复的。
五、AC

六、复杂度分析
- 时间复杂度:
O
(
n
)
O(n)
O(n) ,
n
n
n是
n
u
m
s
nums
nums的大小,二次遍历
n
u
m
s
nums
nums的时间复杂度是
O
(
n
)
O(n)
O(n)。
- 空间复杂度:
O
(
1
)
O(1)
O(1),除若干变量使用的常量空间,没有额外使用线性空间。