先说leetcode 46全排列
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations
给定一个数列,给出其每个元素拼接的所有排列组合。
一般这种题采用递归是最方便的了,按照正常思维去走:
1、取出1 或者 2 或者3 ,数组就剩[2,3]或者[1,3]或者[1,2]。
2、在1的基础上,如[2,3]再取出2或者3,数组就剩[3]或者[2]。
3、再在2的基础上,如[3]取出3,数组空,把前面依次取的数保存下来,即为一种排列。
代码很简单(python):
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
result=[]
def TraceBack(nums,tmp):
if not nums:
result.append(tmp)
for i in range(len(nums)):
TraceBack(nums[:i]+nums[i+1:],tmp+[nums[i]])
TraceBack(nums,[])
return result
tips:result类似于一个全局变量,可以被每一次递归访问,节省很多参数拷贝过程
再说47全排列2
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations-ii
与1唯一不同的是输入会有重复项
做法也很简单,先对输入进行排列,再在每层for循环时加一句判断,判断该元素是否在之前已经被访问过了,如[1,1,2]中的第二个1,如果它也进行递归排列,生成的结果只会与第一个1一模一样。所以,在每一层遍历的时候,大胆地把重复的去掉即可,这种思想也被称之为剪枝。
代码只在1的代码上添加了两句:
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
result=[]
def backtrack(nums,tmp):
if not nums:
result.append(tmp)
for i in range(len(nums)):
if i!=0 and nums[i]==nums[i-1]:#2添加
continue#2添加
backtrack(nums[:i]+nums[i+1:],tmp+[nums[i]])
backtrack(nums,[])
return result