Leetcode31. 下一个排列
题目:
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
题解:
1.对数组nums从后往前查找,找到第一个比后面所有元素都小的元素位置 iii;
2.如果 i=0i=0i=0,说明数组是降序排列的,那么将数组反转一下得到结果;
3.如果 i≠0i\neq0i=0,从后往前遍历数组,找到第一个比nums(i)nums(i)nums(i)大的值所在的索引j,将i和j位置的数据互换位置;再对索引是 i+1i+1i+1 到数组的最后的数据进行反转即可。
java代码:
public static int[] nextPermutation(int[] nums) {
int i = nums.length - 2;
while (i >= 0 && nums[i] > nums[i + 1]) {
i--;
}
if (i >= 0) {
int j = nums.length - 1;
while (j >= 0 && nums[i] > nums[j]) {
j--;
}
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int tmp1 = nums[left];
nums[left] = nums[right];
nums[right] = tmp1;
left++;
right--;
}
return nums;
}
scala代码:
/**
*
* @param nums
*/
def nextPermutation(nums: Array[Int]): Array[Int] = {
var i = nums.length - 2
while (i >= 0 && nums(i + 1) <= nums(i)) {
i = i - 1
}
//数组是降序排列
if (i == -1) {
var a = 0
var b = nums.length - 1
while (a < b) {
//当找到第一个比nums(i)大的值时,交换两个值的位置
val tmp = nums(a)
nums(a) = nums(b)
nums(b) = tmp
a = a + 1
b = b - 1
}
} else {
var j = nums.length - 1
while (j >= 0 && nums(i) > nums(j)) {
j = j - 1
}
//当找到第一个比nums(i)大的值时,交换两个值的位置
val tmp = nums(i)
nums(i) = nums(j)
nums(j) = tmp
//再交换i位置之后的数据,按照从小到大排列
var k = nums.length - 1
while (i + 1 < k) {
val tmp = nums(i + 1)
nums(i + 1) = nums(k)
nums(k) = tmp
i = i + 1
k = k - 1
}
}
nums
}
本文详细解析了LeetCode第31题“下一个排列”的算法思路及实现,介绍了如何通过一次遍历找到升序序列前的最大数,并通过交换和反转操作生成下一个字典序排列。
1506

被折叠的 条评论
为什么被折叠?



