?
排列和组合的区别在于,排列对“顺序”有要求。比如 [1,2] 和 [2,1] 是两个不同的结果。
这就导致了同一个元素 在同一条路径中不可重复使用,在不同的路径中可以重复使用。?
比如数组 [1,2,3] ,在第一条路径 [1,2,3]中,1只能出现一次。但是在另一条选择路径 [2,1,3] 中,1或者在其他路径中出现过的元素仍然可以继续使用。
为了保证 “同一元素在一条路径中只能使用一次” ,我们需要额外维护一个boolean数组用于记录元素的使用情况:已经使用过的元素标记为 “true” ,没有使用过的元素标记为 “false”;
套用框架:
class Solution {
//用于存放子结果的容器
List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> permute(int[] nums) {
//存放路径的容器
LinkedList<Integer> track = new LinkedList<>();
//用于记录元素使用情况的boolean数组
//数组初始值全为false,意为“该元素尚未使用”
boolean[] used = new boolean[nums.length];
backtrack(nums,track,used);
return res;
}
//backtrack函数参数选用:函数参数设置时只需要看看这个函数想达到目的
//需要那些参数,然后把这些参数全丢尽括号中就好了
void backtrack(int[] nums,LinkedList<Integer> track,
boolean[] used){
//终止条件:当子集收集满后放入最终解集中
if(track.size() == nums.length){
res.add(new LinkedList(track));
return;
}
//遍历选择列表
for(int i = 0;i < nums.length;i++){
//如果这个元素已经使用过了,就跳过这个选择
if(used[i]){
continue;
}
//做选择
track.add(nums[i]);
//更新元素使用情况——“已使用”
used[i] = true;
//进入下一层决策
backtrack(nums,track,used);
//撤销选择
track.removeLast();
//更新元素使用情况——“未使用”
used[i] = false;
}
}
}