算法_回溯_全排列II(含去重方法总结)

全排列II

leetcode链接

1.解法

这道题和简单全排列的区别在于,集合中有重复元素,所以我们只要使用一种方法去重即可。

如果不明白简单全排列要怎么做的,可以看我以前的博客(全排列

先画出树图:
在这里插入图片描述
首先我们先讲为什么需要去重,换句话说,为什么会产生重复解?

举个例子,比如[1,1,2]。

对于第一个1而言,如果先把他选出来,那么对于剩余集合[1,2]而言,就可以产生[1,1,2]、[1,2,1]两个解。

然后我们来看第二个1,如果先把他选出来,那么剩余集合也是[1,2],这样也会产生两个解,[1,1,2]、[1,2,1],和上面就重复了

因此我们需要有一个集合来记录这个集合中哪些元素已经被选择过了,这样在后面做选择时,如果第一个选的元素已经在这个集合里面了,就直接跳过。

举个例子,还是[1,1,2]。做记录的集合我们记为used1

首先选择第一个1,然后产生两个解[1,1,2]、[1,2,1],并且1进入used1。

然后选择第二个1,发现1已经在used1中了,直接跳过。这样就避免了重复解。

所以我们在之前简单全排列的基础上加上used1来记录即可。

def permuteUnique(nums):
    result = []
    path = []
    used = [0] * len(nums)

    def backtracking(nums,used):
        used1 = set() # 注意used1要声明在递归函数里面,因为(树中)每下一层used1就要重新记录
        if len(nums)==len(path):
            path1 = path.copy()
            result.append(path1)
            return

        for i in range(len(nums)):
            if used[i]==1:
                continue

            if nums[i] in used1:
                continue

            path.append(nums[i])
            used1.add(nums[i]) # 添加即可
            used[i] = 1
            backtracking(nums,used)
            used[i] = 0
            path.pop()

    backtracking(nums,used)
    return result

2.总结

去重的方法:

  1. 组合问题:集合中含重复元素:
nums = sorted(nums)

if i > startindex and nums[i] == nums[i-1]:
	continue
  1. 组合问题:集合中含重复元素,并且集合不允许排序
used = set()

for i in range():
	used.add(nums[i])
  1. 排列问题:集合中含重复元素(和第二种情况一致)
used = set()

for i in range():
	used.add(nums[i])
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值