前言
仅记录学习笔记,如有错误欢迎指正。
题目
全排列(给定一个没有重复数字的序列,返回其所有可能的全排列。)示例
- 输入: nums = [1,2,3]
- 输出: [
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
解法
public List<List<Integer>> permute(int[] num){
List<List<Integer>> res = new ArrayList<>();
List<Integer> track = new ArrayList<>();
dfsNew(num,track,res);
return res;
}
public void dfsNew(int[] num, List<Integer> track, List<List<Integer>> res){
//判断是不是到最后了
if(track.size()==num.length){
res.add(new ArrayList<>(track));
}else{
for(int i =0;i<num.length;i++){
//决策树中已经存在不能再次选择
if(track.contains(num[i])){
continue;
}
track.add(num[i]);
//进入下一步决策
dfsNew(num,track,res);
//取消选择 移出最后一位
track.remove(track.size()-1);
}
}
}
题目
组合问题 给定两个数字n,k,算法输出[1,n]中k个数字的所有组合示例
- 输入:n=4 k=2
- 输出: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
解法
List<List<Integer>> res1 = new ArrayList<>();
public List<List<Integer>> combine(int n,int k) {
List<Integer> track = new ArrayList<>();
dfs1(n,k,1,track);
return res1;
}
private void dfs1(int n,int k , int start, List<Integer> track) {
if(track.size()==k){
res1.add(new ArrayList<>(track));
return;
}
for(int i = start;i<=n;i++){
if(!track.isEmpty() && i <= track.get(0)){
continue;
}
if(track.size()==0 && i==n){
break;
}
track.add(i);
dfs1(n,k,start+1,track);
track.remove(track.size()-1);
}
}
题目
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 回溯法 子集问题示例
- 输入: nums = [1,2,3]
- 输出: [
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
解法
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
List<Integer> list = new ArrayList<>();
//带下标确认从哪个开始
dfs(nums, 0, list);
return res;
}
public void dfs(int[] nums, int start, List<Integer> track) {
res.add(new ArrayList<>(track));
//i从start开始递增 避免和前面加入的重复了
for(int i=start;i<nums.length;i++) {
track.add(nums[i]);
dfs(nums,i+1,track);
track.remove(track.size()-1);
}