17.电话号码的字母组合
public static final String[] map = new String[]{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public static char[] d,path;
public List<String> letterCombinations(String digits) {
ArrayList<String> ans = new ArrayList<>();
int n = digits.length();
if(n==0) return List.of();
this.d=digits.toCharArray();
path = new char[n];
dfs(0,ans);
return ans;
}
public void dfs(int i, ArrayList<String> ans){
if(i==d.length){
ans.add(new String(path));
return;
}
for(char c : map[d[i]-'0'].toCharArray()){
path[i] = c;
dfs(i+1, ans);
}
}
39.组合总和
注意这道题说,可以重复选某个元素,对应于完全背包。
public List<List<Integer>> combinationSum(int[] candidates, int target) {
// 从小到大排序,便于剪枝
Arrays.sort(candidates);
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
dfs(0,target,candidates,ans,path);
return ans;
}
public void dfs(int i, int remains, int[] candidates, List<List<Integer>> ans,List<Integer> path){
// 找到一个合法的组合;
if(remains==0){
ans.add(new ArrayList<>(path));
return;
}
// 剪枝,如果剩余值都比当前值小,就跳出,没必要选了
if(i==candidates.length || remains<candidates[i]){
return;
}
// 选
path.add(candidates[i]);
// 可以重复选很多次
dfs(i,remains-candidates[i],candidates,ans,path);
// 恢复现场
path.remove(path.size()-1);
// 不选
dfs(i+1,remains,candidates,ans,path);
}