精选力扣500题 第32题 LeetCode 31. 下一个排列c++ / java 详细题解
Posted 林深时不见鹿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了精选力扣500题 第32题 LeetCode 31. 下一个排列c++ / java 详细题解相关的知识,希望对你有一定的参考价值。
1、题目
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]
示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]
示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]
示例 4:
输入:nums = [1]
输出:[1]
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 100
2、思路
(找规律) O ( n ) O(n) O(n)
对于数组排列问题,我们可以知道,如果一个数组是升序数组,那么它一定是最小的排列。如果是降序数组,那么它一定是最大的排列。而找下一个排列就是从后往前寻找第一个出现降序的地方,把这个地方的数字与后边第一个比它大的的数字交换,再把该位置之后整理为升序。
- 1、从数组末尾往前找,找到 第一个 位置
k
,使得nums[k-1] < nums[k]
,则从后往前看nums[k-1],nums[k]
满足降序。 - 2、如果
k <=0
,说明不存在这样的k
,则数组是不递增的,直接将数组逆转即可。 - 3、如果存在这样的
k
,则让t = k
,从前往后找到第一个位置t
,使得nums[t] <= nums[k-1]
,则nums[t-1]
就是第一个大于nums[k-1]
的数。 - 4、交换
nums[k-1]
与nums[t-1]
,然后将数组从k
到末尾部分逆转。
图示过程
时间复杂度:遍历整个数组需要
O
(
n
)
O(n)
O(n)的时间
3、c++代码
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int k = nums.size() - 1;
while (k > 0 && nums[k - 1] >= nums[k]) k -- ; //
if (k <= 0) {
reverse(nums.begin(), nums.end());
} else {
int t = k;
while (t < nums.size() && nums[t] > nums[k - 1]) t ++ ;
swap(nums[t - 1], nums[k - 1]);
reverse(nums.begin() + k, nums.end());
}
}
};
4、java代码
class Solution {
public void nextPermutation(int[] nums) {
int k = nums.length - 1;
while (k > 0 && nums[k - 1] >= nums[k]) k--;
if (k == 0) { // 说明是最大值, 返回最小值
reverse(nums, 0, nums.length - 1);
} else {
int t = k;
while (t < nums.length && nums[t] > nums[k - 1]) t++;
swap(nums, k - 1, t - 1);
reverse(nums, k, nums.length - 1);
}
}
// 翻转nums[i...j]
private void reverse(int[] nums, int i, int j) {
while (i < j) {
swap(nums, i, j);
i++; j--;
}
}
// 交换nums[i], nums[j]
private void swap(int[] nums, int i, int j) {
int t = nums[i]; nums[i] = nums[j]; nums[j] = t;
}
}
原题链接:31. 下一个排列
以上是关于精选力扣500题 第32题 LeetCode 31. 下一个排列c++ / java 详细题解的主要内容,如果未能解决你的问题,请参考以下文章
精选力扣500题 第20题 LeetCode 704. 二分查找c++详细题解
精选力扣500题 第8题 LeetCode 160. 相交链表 c++详细题解
精选力扣500题 第61题 LeetCode 78. 子集c++/java详细题解
精选力扣500题 第6题 LeetCode 912. 排序数组c++详细题解