跳到主要内容

Permutations II

描述

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example, [1,1,2] have the following unique permutations: [1,1,2], [1,2,1], and [2,1,1].

next_permutation()

直接使用std::next_permutation(),代码与上一题相同。

重新实现 next_permutation()

重新实现std::next_permutation(),代码与上一题相同。

递归

递归函数permute()的参数p,是中间结果,它的长度又能标记当前走到了哪一步,用于判断收敛条件。

扩展节点,每次从小到大,选一个没有被用光的元素,直到所有元素被用光。

本题不需要判重,因为状态装换图是一颗有层次的树。

# Permutations II
# 深搜,时间复杂度O(n!),空间复杂度O(n)
class Solution:
def permuteUnique(self, nums):
nums.sort() # 必须排序
result = [] # 最终结果
path = [] # 中间结果

# 记录每个元素的出现次数
counter_map = {}
for i in nums:
counter_map[i] = counter_map.get(i, 0) + 1

# 将HashMap里的pair拷贝到一个数组里
counters = []
for key, value in counter_map.items():
counters.append(Pair(key, value))
counters.sort()

# 每个元素选择了多少个
selected = {p.key: 0 for p in counters}

self.n = len(nums)
self.permute(counters, selected, path, result)
return result

def permute(self, counters, selected, path, result):
if self.n == len(path): # 收敛条件
result.append(path[:])

# 扩展状态
for counter in counters:
if selected[counter.key] < counter.value:
path.append(counter.key)
selected[counter.key] += 1
self.permute(counters, selected, path, result)
path.pop()
selected[counter.key] -= 1

class Pair:
def __init__(self, key, value):
self.key = key
self.value = value

def __lt__(self, other):
if self.key < other.key:
return True
elif self.key > other.key:
return False
else:
return self.value < other.value

相关题目