一、题目分析
将给定的一个数组,进行所有组合,挑选出所有比原数组所代表的数字大的数组中最小的那个
二、方法与代码
(1)大神
基于我的实现的优化:
- 因为停止位置往右都是逆序,所以只需要判断是否比哨兵大就行,一直向右找下去就会找到最小的较大数,而不需要特意记录两数相减的最小差
- 对数组的排序:由于我们找到的较大数是最后一个,即使是重复的也是最后一个,如 [2] 3 3 (3) 1找到的是最后一个3,交换后为(3) 3 3 [2] 1,剩下待排序的部分数组为逆序,所以只需要倒序即可
n = len(nums)
for i in range(n-1, 0, -1):
if nums[i] > nums[i-1]:
j = i
while j < n and nums[j] > nums[i-1]:
idx = j
j += 1
nums[idx], nums[i-1] = nums[i-1], nums[idx]
for k in range((n-i)//2):
nums[i+k], nums[n-1-k] = nums[n-1-k], nums[i+k]
break
else:
nums.reverse()
(2)官方
思路:从数组末尾开始向左,当元素逆序时继续向左,当出现打乱逆序的较小数时,停在此处另为pos,从该位置右边寻找比该数大的最小的一个数,交换这两个数,再将pos右边的所有数字进行排序,结果即为比所有原数组大的数组中最小的数
我的实现:
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
i= len(nums)-1
while i >=0:
if i==len(nums)-1 or nums[i]>=nums[i+1]:
i -= 1
continue
else:
minbig, mingap = i, sys.maxsize
for j in range(i+1,len(nums)):
gap = nums[j]-nums[i]
if gap==1:
minbig=j
break
if gap<mingap and gap>0:#gap must bigger than 0
mingap=gap
minbig = j
if nums[minbig] != nums[i]:
nums[i],nums[minbig]=nums[minbig],nums[i]
break
i -= 1
if i ==-1:
nums.reverse()
else:
temp=nums[i+1:]
temp.sort()
nums[i+1:] = temp
(3)我的
暴力。。寻找所有排列组合,将所有结果升序排序,找到和原数组相同的数的位置,其下一个位置就是题目要求
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
array = ""
com = []
for i in nums:
array+=str(i)
com.append(str(i))
permutations = itertools.permutations(array, len(array))
t = sorted(list(permutations))
for i, p in enumerate(t):
# print(i,list(p),com)
if list(p)==com:
if i+1 < len(t):
tt=list(t[i+1])
else:
tt=list(t[0])
for i,j in enumerate(tt):
nums[i] = int(j)