给定一个不含重复数字的数组 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 <= nums.length <= 6
-10 <= nums[i] <= 10
nums
中的所有整数 互不相同回溯算法的基本思想是在问题的解空间树中,按照深度优先搜索的策略,从根节点出发深度探索解空间树。当探索到某一节点时,先判断该节点是否包含问题的解,如果包含,就从该节点出发继续探索下去,如果该节点不包含问题的解,则逐层向其祖先节点回溯。若用回溯法求问题的所有解时,要回溯到根,且根节点的所有可行的子树都要已被搜索遍才结束。而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。
n
和 k
,返回范围 [1, n]
中所有可能的 k
个数的组合。n×n
的棋盘上放置 n
个皇后,使得它们彼此之间不能相互攻击(即任意两个皇后都不能处于同一行、同一列或同一斜线上)。全排列的话,比如示例中的[1,2,3],每个元素都要出现在每个位置上,而且不能重复使用元素。所以回溯的基本思路应该是,每次选择一个未被使用的元素,加入到当前路径中,直到路径长度等于原数组长度,这时候就得到一个排列,然后回溯回去,尝试其他可能性。
比如,对于nums数组中的每个元素,如果未被使用,就把它加入当前路径,标记为已使用,然后递归地进行下一层选择。当路径长度等于数组长度时,将当前路径的拷贝加入结果列表。递归返回后,需要撤销刚才的选择,也就是从路径中移除最后一个元素,并标记该元素为未使用,这样才能继续尝试其他可能性。
需要一个结果列表来保存所有可能的排列,还需要一个临时列表来记录当前的路径。另外,为了标记哪些元素已经被使用过,可以用一个布尔数组来记录每个元素是否被使用过。
class Solution {
public List> permute(int[] nums) {
List> result = new ArrayList<>(); //结果列表
//输出所有全排列
backtrack(nums, new ArrayList<>(), new boolean[nums.length], result);
return result;
}
private void backtrack(int[] nums, List current, boolean[] used, List> result){
//终止条件,当当前排列的长度等于数组的长度时,说明已经生成了一个完整的排列
if(current.size() == nums.length){
result.add(new ArrayList<>(current)); //注意要创建副本(拷贝),因为后续回溯过程会修改current列表
return; //结束当前递归调用,回溯到上一层
}
for(int i = 0; i < nums.length; i++){
if(!used[i]){
used[i] = true;
current.add(nums[i]);
// 递归调用回溯函数,继续生成排列
backtrack(nums,current,used,result);
// 回溯操作:撤销之前的选择
// 从当前排列中移除最后添加的元素
current.remove(current.size() - 1);
// 标记当前元素为未使用,以便后续可以再次使用
used[i] = false;
}
}
}
}
需要注意的是,Java中的List是引用类型,所以在将path添加到结果列表时,必须创建一个新的ArrayList,否则后续对path的修改会影响结果中已保存的列表。也就是说,当路径完成时,应该res.add(new ArrayList<>(path)),而不是直接添加path本身。
backtracka函数解释
nums
:这是原始的整数数组,我们要基于这个数组生成所有可能的排列。current
:它是一个 List
,用于存储当前正在生成的排列。在递归过程中,会不断地向这个列表中添加元素,以逐步构建出一个完整的排列。used
:这是一个布尔类型的数组,长度和 nums
数组相同。used[i]
表示 nums[i]
这个元素是否已经在当前排列 current
中被使用过。如果 used[i]
为 true
,则表示 nums[i]
已被使用;如果为 false
,则表示未被使用。result
:这是一个二维列表,用于存储最终生成的所有排列。当一个完整的排列生成后,会将其添加到 result
中。