回溯
参考这里。
其实也算是蛮典型的回溯,利用递归每次向 temp 里添加一个数字,数字添加够以后再回来进行回溯,再向后添加新的解。
可以理解成一层一层的添加,每一层都是一个 for 循环。
每调用一层就进入一个 for 循环,相当于列出了所有解,然后挑选了我们需要的。其实本质上就是深度优先遍历 DFS。
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
backtrack(list, new ArrayList<>(), nums);
return list;
}
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
} else{
for(int i = 0; i < nums.length; i++){
if(tempList.contains(nums[i])) continue; // 已经存在的元素,跳过
tempList.add(nums[i]); //将当前元素加入
backtrack(list, tempList, nums); //向后继续添加
tempList.remove(tempList.size() - 1); //将 tempList 刚添加的元素,去掉,尝试新的元素
}
}
}
还有一位大佬的位运算解法,参考: