题目链接:https://leetcode.com/problems/next-permutation/
今天中午笔友突然让我看这个题,心血来潮就思考了一下有了思路就开始码了!!!
so interesting a problem!!!
the lexicographically next greater permutation of numbers这句话需要wikipedia一下,在google上找了个直观的例子https://www.ideserve.co.in/learn/next-greater-number-using-same-digits
就是说nums中所有数字的全排列中大于nums原排列的数值的最小数的排列,这话太他妈拗口!!!
笔友先给我看了这个题让我看看他的思路:
from itertools import permutations
class Solution:
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
flag = False
if len(nums) == 0 or len(nums) == 1:
flag = not flag
nums_permutation = list(permutations(nums))
if flag is False:
for index in nums_permutation:
index = list(index)
if index > nums:
nums = index
flag = True
break
if flag is False:
nums.sort()
print("nums", nums)
这个Python版本的解法就是刚刚那句拗口的话的代码表示,就是找出全排列所有情况,然后排序找到目标排列!!!显然itertools.permutations()不是原地操作,全排列操作的时间复杂度为O(n!),n为数组长度。
下面我给出一个解法:经过举例子观察发现,要做交换的两个数位(i,j,i<j)越低越好,而且越接近越好,待交换的位置为[nums.length-2:0],所以从nums.length-2开始向后(一直到nums.length-1)搜索那个符合条件的索引值。搜索到后再对[i+1:nums.length-1]的元素进行快排。
虽然问题定义复杂,但是思路还是很清晰的!!!上代码:
class Solution {
public void nextPermutation(int[] nums) {
if(nums==null || nums.length==0 || nums.length==1)
return;
int i=nums.length-2,index=0;
boolean flag=false;
for(;i>=0;i--)
{
int min_dist=Integer.MAX_VALUE;
for(int j=i+1;j<nums.length;j++)
{
if(nums[j]>nums[i] && nums[j]-nums[i]<min_dist)
{
min_dist=Math.min(min_dist,nums[j]-nums[i]);
index=j;
flag=true;
}
}
if(flag)
{
swap(nums,i,index);
break;
}
}
Arrays.sort(nums,i+1,nums.length);
}
public void swap(int[] nums,int i,int j)
{
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}