如果有明显的递推痕迹,直接dp表顺序填写,考虑初始化的意义。如果没有规则需要探索,就考虑回溯,考虑合法的边界
Problem: LCR 079. 子集
[TOC]
思路
// 子集:子集型回溯,“选择不选” 和 “枚举选哪个”
//生成子集的思考方式:
// ===========【从 “输入” 的角度】=====================
// 递归入口和入口:枚举范围从 i [ 0 ~ n)
// 当前操作?:每一层要做的事情,这个元素,选择 或者 不选择
// 子问题: 下标 >= i层 “选择” 或 “不选择”,构造子集
// 下一个子问题:下标 >= i+1 层 “选择” 或 “不选择”,构造子集
Code
class Solution {
int[] nums;
List<List<Integer>> res = new ArrayList<>();
List<Integer> pick = new ArrayList();
public List<List<Integer>> subsets(int[] nums) {
this.nums = nums;
int n = nums.length;
dfs(0);
return res;
}
public void dfs(int i){
if(i == nums.length){
//有效结果
//全局变量拷贝为每个有效答案,形成结果
ArrayList<Integer> copy = new ArrayList<>();
copy.addAll(pick);
res.add(copy);
return;
}
//“不选”
dfs(i+1);
//“选择”
int x = nums[i];
pick.add(x);
dfs(i+1);
//"恢复递归前的样子"
pick.remove(pick.size()-1);
}
}