往期博客:
目录
题目
给定一个不含重复数字的数组
nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
题目分析
已知:不含重复数字的数组 nums
目的:全排列
要求:返回所有全排列(无序)
示例
示例1
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例2
输入:nums = [0,1] 输出:[[0,1],[1,0]]
示例3
输入:nums = [1] 输出:[[1]]
解析
回溯法
对于1,2,3三个数,如果我们不考虑是否重复,对三个数字进行全排列,可以包含如下排列
但是题目要求不能出现重复的数组,且存在的另一个要求就是数组长度要等于3,则满足要求的如下
该怎么知道数字是否重复呢?这里我们可以用一个哈希表,哈希表的key为数字1,2,3,哈希表的value为Ture或者False,当数字前面已经出现时为Ture,否则为False,如下
当value全为True时进行回溯,如下,先由3回溯到2,并将3的value变为False,诧然是否还有满足的数组,如果没有再从2回溯到1,并将2的value变为False
此时有2,3两个数字可以用,因为第二个数是2的已经用过了,所以第二个数用3
同理,当第一个数为2,3时为同样的过程。
代码
python
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
result = [] #存储最后结果
visited = {} #哈希表
for num in nums:
visited[num] = False # 将每个数字的value设置为False
self.backtracking(nums, result, visited, [])
return result
def backtracking(self, nums, result, visited, ls):
if len(ls) == len(nums): # 当长度等于数组长度时,停止回溯
result.append(ls[:]) # 将最后所有排列数组加入result数组中
return
for num in nums:
if not visited[num]: # 如果num的value为False,则加入列表
ls.append(num)
visited[num] = True # 将num的value设置为True
self.backtracking(nums, result, visited, ls)
ls.pop() # 进行回溯,并将当前数字删了,将数字对应的value同时变为False
visited[num] = False
Java
class Solution {
// Time Complexity: O(N*N!)
// Space Complexity:O(N)
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
HashMap<Integer, Boolean> visited = new HashMap<>();
for (int num : nums) {
visited.put(num, false);
}
backtracking(nums, result, visited, new ArrayList<>());
return result;
}