I'll introduce a method without using the permutation tree.
For next_perm:
- From the right to the left, find the first num[i-1] < num [i], record ii = i-1;
- Find the minimal/rightmost number larger than num[ii] from ii's right. record its index jj (same value, choose righter; diff value, choose smaller)
- swap num[ii] and num[jj]
- Then reverse the array from ii + 1 to end.
For prev_perm:
- From the right to the left, find the first num[i-1] > num [i], record ii = i-1;
- Find the maximum/rightmost number less than num[ii] from ii's right. record its index jj (same value, choose righter; diff value, choose larger)
- swap num[ii] and num[jj]
- Then reverse the array from ii + 1 to end.
class Solution:
def permuteUnique1(self, nums):
nums.sort()
res,l = [],len(nums)
def dfs(depth):
if (depth == l):
res.append(list(nums))
return
vis = set() #对这一层去重即可
for i in range(depth,l):
if (i == depth or nums[i] not in vis):
vis.add(nums[i])
nums[depth],nums[i] = nums[i],nums[depth]
dfs(depth+1)
nums[depth],nums[i] = nums[i],nums[depth]
dfs(0)
return res
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
arr = sorted(nums, reverse=True)
def next_perm(arr):
l,ii = len(arr),-1
for i in range(l-1,0,-1):
if (arr[i-1] < arr[i]):
ii = i-1
break
if ii==-1:
return None
ii,jj=i-1,i
for j in range(jj+1,l):
if arr[ii] < arr[j] and arr[j] <= arr[jj]:
jj = j
arr[ii],arr[jj] = arr[jj],arr[ii]
arr[ii+1:]=arr[ii+1:][::-1]
return arr
def prev_perm(arr):
l,ii = len(arr),-1
for i in range(l-1,0,-1):
if (arr[i-1] > arr[i]):
ii = i-1
break
if ii==-1:
return None
ii,jj=i-1,i
for j in range(jj+1,l):
if arr[ii] > arr[j] and arr[j] >= arr[jj]:
jj = j
arr[ii],arr[jj] = arr[jj],arr[ii]
arr[ii+1:]=arr[ii+1:][::-1]
return arr
res = []
prev = list(arr)
while (prev):
res.append(prev)
prev = prev_perm(list(prev))
return res
s = Solution()
#print(s.permuteUnique([1,1,2]))
#print(s.permuteUnique([1,1,2]))
print(s.permuteUnique([0,0,0,1,9]))
相似问题,这个坑在于one swap:
1053. Previous Permutation With One Swap
Medium
80179Add to ListShare
Given an array A
of positive integers (not necessarily distinct), return the lexicographically largest permutation that is smaller than A
, that can be made with one swap (A swap exchanges the positions of two numbers A[i]
and A[j]
). If it cannot be done, then return the same array.
Example 1:
Input: [3,2,1]
Output: [3,1,2]
Explanation: Swapping 2 and 1.
Example 2:
Input: [1,1,5]
Output: [1,1,5]
Explanation: This is already the smallest permutation.
Example 3:
Input: [1,9,4,6,7]
Output: [1,7,4,6,9]
Explanation: Swapping 9 and 7.
Example 4:
Input: [3,1,1,3]
Output: [1,3,1,3]
Explanation: Swapping 1 and 3.
Note:
1 <= A.length <= 10000
1 <= A[i] <= 10000
Accepted
8,146
Submissions
17,174
class Solution:
def prevPermOpt1(self, A):
la = len(A)
if (la <= 1):
return A
ii = -1
for i in range(la-1,0,-1):
if (A[i-1] > A[i]):
ii = i-1
break
if (ii < 0):
return A
jj = ii+1
for i in range(ii+1,la):
if (A[i] < A[ii] and A[i] > A[jj]):
jj = i
#A[ii+1:] = reversed(A[ii+1:])
A[ii],A[jj] = A[jj],A[ii]
return A
s = Solution()
print(s.prevPermOpt1([1,9,4,6,7]))