給定一個可包含重複數字的整數數組 nums
,返回所有不重複的排列。
輸入: nums = [1, 1, 2]範例 2:
輸出: [[1,1,2],[1,2,1],[2,1,1]]
輸入: nums = [1, 2, 3]
輸出: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
此題與 LeetCode 46. Permutations 非常相似,不同的是,輸入的數組可能包含重複的元素,因此我們需要確保返回的排列是唯一的。
解決此問題的關鍵是避免重複。可以採用以下方法:
使用回溯法生成排列,並在選擇元素時進行去重處理:
used
來標記哪些元素已經被使用。class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
def backtrack(path, used, res):
if len(path) == len(nums):
res.append(path[:]) # 儲存當前排列
return
for i in range(len(nums)):
# 跳過已使用的元素
if used[i]:
continue
# 跳過重複的元素
if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:
continue
# 選擇當前元素
used[i] = True
path.append(nums[i])
backtrack(path, used, res)
# 回溯:撤銷選擇
path.pop()
used[i] = False
nums.sort() # 排序以便去重
res = []
used = [False] * len(nums)
backtrack([], used, res)
return res
used
。class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
def backtrack(start, res):
if start == len(nums):
res.append(nums[:]) # 儲存當前排列
return
seen = set() # 用來記錄本層中已使用的數字
for i in range(start, len(nums)):
# 如果當前數字已被使用,則跳過
if nums[i] in seen:
continue
seen.add(nums[i])
# 交換當前數字到起始位置
nums[start], nums[i] = nums[i], nums[start]
backtrack(start + 1, res)
# 回溯:交換回來
nums[start], nums[i] = nums[i], nums[start]
nums.sort() # 排序以便去重
res = []
backtrack(0, res)
return res
seen
。itertools.permutations
+ 去重)itertools.permutations
生成所有排列。from itertools import permutations
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
return list(set(permutations(nums)))
希望這篇教學能幫助大家輕鬆理解這道題目!