一、题目描述:
整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。
例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。
必须 原地 修改,只允许使用额外常数空间。
-
示例 1:
- 输入:nums = [1,2,3]
- 输出:[1,3,2]
-
示例 2:
- 输入:nums = [3,2,1]
- 输出:[1,2,3]
-
示例 3:
- 输入:nums = [1,1,5]
- 输出:[1,5,1]
- 提示:
- 1 ≤ n u m s . l e n g t h ≤ 100 1 \leq nums.length \leq 100 1≤nums.length≤100
- 0 ≤ n u m s [ i ] ≤ 100 0 \leq nums[i] \leq 100 0≤nums[i]≤100
二、解决思路和代码
1. 解决思路
- 分析:如果完全理解题目的意思,这道题还是很简单的。这里找一个长一点的序列nums=[1 5 6 4 3 2 1]
- 理解一下题意:将序列中的数字组合成一个整数,将所有数字的不同组合按照从小到大排序:
- 1123456 < 1123465 < 1123546 < 1123564 < 1123645 < 1123654 < 1124356 < 1124365 < . . . 1123456<1123465<1123546<1123564<1123645<1123654<1124356<1124365<... 1123456<1123465<1123546<1123564<1123645<1123654<1124356<1124365<...
- 1123456的下一个排列就是1123465
- 1123465的下一个排列就是1123546
- … 依次类推
- 1564321的下一个排列就是1612345
- 解题步骤
-
step1: 找到右边起第一个极大值的前一个数值: nums[right]
-
step2: 从最右边开始找 nums[right:] 中第一个比 nums[right] 大的数值 nums[search]
-
step3: 交换 nums[right] 和 nums[search]
-
step4: 反转 nums[right:] 数值
-
- 理解一下题意:将序列中的数字组合成一个整数,将所有数字的不同组合按照从小到大排序:
2. 代码
from typing import *
class Solution:
def swap(self, nums: List[int], i:int, j:int) -> None:
temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
return
def revised(self, nums: List[int], i:int, j:int) -> None:
start, end = i, j
while start<end:
self.swap(nums, start, end)
start += 1
end -= 1
return
def nextPermutation(self, nums: List[int]) -> None:
right = len(nums)-2
while right>=0 and nums[right]>=nums[right+1]: right -= 1
if right>=0:
search = len(nums)-1
while search>right and nums[search]<=nums[right]: search-=1
self.swap(nums, search, right)
self.revised(nums, right+1, len(nums)-1)
else:
self.revised(nums, 0, len(nums)-1)
return