问题描述:
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
思路:
感觉解题的主要难点还是在找规律和求解思路上。
1.首先,是要将数字数组,按照字典序排列,找出第二大的。如果没有,就直接升序排列。
2.查找顺序应该是右→左。找到第一个n[i]>num[i-1],交换n[i]和n[i-1]的值,再从第i个位置开始,对后面的元素升序排列。
3.对于没有更大的排列(如:3,2,1 → 1,2,3),不用按照特殊情况处理,按照2.查找结果即i=0,那么对所有元素升序即可。
java版本:
class Solution {
public void nextPermutation(int[] nums) {
int i = nums.length-1;
while(i>0&&(nums[i]<=nums[i-1])){
i--;
}
if(i>0){
int j = nums.length-1;
while(j>=0&&(nums[j]<=nums[i-1])){
j--;
}
swap(nums,i-1,j);
}
reverse(nums,i);
}
public void reverse(int[] nums,int i){
int j = nums.length-1;
while(i<j){
swap(nums,i,j);
i++;
j--;
}
}
public void swap(int[] nums, int a, int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
python版本:
与java不一样的是swap函数与reversed函数可直接调用:
tips:在Python中,a和b的值不会发生交换,但位于当前命名空间中的标记(如a和b)是可以交换的。而对象本身是仍然保留。
所以与其调用一个swap(a, b),你倒不如使用:a,b = b,a。
class Solution(object):
def swap(self,a,b):
return b,a
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
l = len(nums)
i = l-1
j = l-1
while i>0 and nums[i]<=nums[i-1]:
i-=1
if i>0:
while nums[j]<=nums[i-1]:
j-=1
nums[i-1],nums[j] = self.swap(nums[i-1],nums[j])
nums[i:l] = reversed(nums[i:l])