题目链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/
思路:还是典型的组合问题,只不过每次递归需要替换for循环的集合。
组合类型的题为什么需要起始索引?是因为为了避免递归走回头路,出现2,3和3,2的问题,从组合角度上来看这两种就是一种,但是对于固定的单一集合来说确实是如此,需要起始索引,避免走回头路,而对于多集合来说,每个集合都不重复,没有走回头路这一说,故多集合不需要起始索引,本题即是。
class Solution {
String[] strList = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
StringBuilder builder;
List<String> list;
public List<String> letterCombinations(String digits) {
builder = new StringBuilder();
list = new ArrayList<>();
if(digits.length() == 0) return list;
backTracking(digits, 0);
return list;
}
void backTracking(String digits, int i) {
if (i == digits.length()) {
list.add(builder.toString());
return;
}
String temp = strList[digits.charAt(i)-'0'];
for (int k = 0; k < temp.length(); k++) {
builder.append(temp.charAt(k));
backTracking(digits, i+1);
builder.deleteCharAt(builder.length()-1);
}
}
}
题目链接:https://leetcode.cn/problems/combination-sum/description/
思路:这个新类型,是无重复元素,可以复选,复选的话即是,单条递归链路,a元素可用,向下递归a还得可用,才能满足可复选,故起始索引为startIndex。如果题目是无重复元素,不可复选,起始索引为startIndex+1.
class Solution {
List<List<Integer>> arrayLists;
List<Integer> list;
int sum = 0;
public List<List<Integer>> combinationSum(int[] candidates, int target) {
arrayLists = new ArrayList<>();
list = new ArrayList<>();
backTracking(candidates, target, 0);
return arrayLists;
}
void backTracking(int[] candidates, int target, int index) {
if (sum > target) return;
if (sum == target) {
arrayLists.add(new ArrayList<>(list));
return;
}
for (int i = index; i < candidates.length; i++) {
sum += candidates[i];
list.add(candidates[i]);
backTracking(candidates, target, i);
sum -= candidates[i];
list.remove(list.size()-1);
}
}
}
本题还可以提前剪枝一下,但是从结果上来看没有多大提升,提前预判结果是需要排序的,才能确保后续元素都更大。
List<List<Integer>> arrayLists;
List<Integer> list;
int sum = 0;
public List<List<Integer>> combinationSum(int[] candidates, int target) {
arrayLists = new ArrayList<>();
list = new ArrayList<>();
Arrays.sort(candidates);
backTracking(candidates, target, 0);
return arrayLists;
}
void backTracking(int[] candidates, int target, int index) {
if (sum == target) {
arrayLists.add(new ArrayList<>(list));
return;
}
for (int i = index; i < candidates.length && sum+candidates[i] <= target; i++) {
sum += candidates[i];
list.add(candidates[i]);
backTracking(candidates, target, i);
sum -= candidates[i];
list.remove(list.size()-1);
}
}