组合就要求每一次都从0开始,但是要判断该元素究竟有没有用过,以此来规定每个元素只能出现一次。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
res=[]
path=[]
used=[]
def backtrack(nums,used):
if len(path)==len(nums):
res.append(path[:])
for i in range(0,len(nums)):#与组合不同,排列这里是从0开始,而不是从start开始,因此不需要start
if nums[i] in used:#如果已经使用过就跳过。
continue
used.append(nums[i])
path.append(nums[i])
backtrack(nums,used)#注意这的used已经更新,因为加入了nums[i]
path.pop()
used.pop()
backtrack(nums,[])
return res
47
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
res=[]
path=[]
used=[0]*len(nums)
def backtrack(nums,used,path):
if len(path)==len(nums):
return res.append(path[:])
for i in range(0,len(nums)):
if not used[i]:
if i>0 and nums[i]==nums[i-1] and used[i-1]==0:
continue
used[i]=1
path.append(nums[i])
backtrack(nums,used,path)
path.pop()
used[i]=0
nums=sorted(nums)
backtrack(nums,used,[])
return res
'''明显需要我们同层去重剪枝。这里主要讲解一下
if i>0 and nums[i]==nums[i-1] and used[i-1]==0: continue这句话的意思。
举例[1,1',2]。当第一位选择1的时候,后面选择1'并不会发生重复,但是当第一位选择1的情况遍历完毕。
我们开始在第一位上选择1'的时候,由于此时1还没有使用,所以遍历结果和第一位是1的时候完全相同。因此我们
需要跳过。
如果写成used[i-1]==1也是可以的,但是这样是表示这一个元素的前一个重复元素的used是1,他也是1,跳过。
这样写是到了叶子结点的时候才被剪掉。相比较于上个方法,这样更冗长费时
具体图解可以看https://leetcode-cn.com/problems/permutations-ii/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liwe-2/'''