一、电话号码的字母组合

import java.util.ArrayList;
import java.util.List;
import javax.management.loading.PrivateClassLoader;
public class letterCombinations {
private static final String[] KEYPAD= {
"", //0
"", //1
"abc", //2
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz"
};
public List<String> letterCombinations(String digits) {
List<String>result=new ArrayList<>();
if(digits==null||digits.isEmpty()) {
return result;
}
backtrack(digits,0,new StringBuilder(),result);
return result;
}
private void backtrack(String digits, int index, StringBuilder path, List<String> result) {
// TODO Auto-generated method stub
//当路径长度等于数字串长度,加入到结果列表
if(path.length()==digits.length()) {
result.add(path.toString());
return;
}
//获取当前数字对应的字母集
char digit=digits.charAt(index);
String letterString =KEYPAD[digit-'0'];
//遍历字母集,递归处理下一个数字
for(char c:letterString.toCharArray()) {
path.append(c);
backtrack(digits, index+1, path, result);
//回溯,删除最后添加的字符
path.deleteCharAt(path.length()-1);
}
}
}
String letterString=Keypad[digit-'0'];
在Java里,字符类型(char)本质上是整数类型,它存储的是字符对应的Unicode码点值。数字字符'0'到'9'的Unicode码点是连续的,其范围是从48(对应字符'0')到57(对应字符'9')。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CombinationSum {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
// 排序,方便剪枝
Arrays.sort(candidates);
backtrack(candidates, target, 0, path, result);
return result;
}
private void backtrack(int[] candidates, int remain, int start,
List<Integer> path, List<List<Integer>> result) {
if (remain == 0) {
// 找到符合条件的组合,加入结果集(注意要 new 新的 ArrayList 避免引用问题)
result.add(new ArrayList<>(path));
return;
}
for (int i = start; i < candidates.length; i++) {
if (candidates[i] > remain) {
// 当前元素已超过剩余目标和,由于数组有序,后续元素更大,直接剪枝
break;
}
// 选择当前元素
path.add(candidates[i]);
// 递归,可重复选当前元素,所以 start 还是 i
backtrack(candidates, remain - candidates[i], i, path, result);
// 撤销选择,回溯
path.remove(path.size() - 1);
}
}
public static void main(String[] args) {
CombinationSum solution = new CombinationSum();
int[] candidates = {2, 3, 6, 7};
int target = 7;
List<List<Integer>> result = solution.combinationSum(candidates, target);
for (List<Integer> list : result) {
System.out.println(list);
}
}
}
- 排序与剪枝 :对
candidates
排序后,当candidates[i] > remain
时,后续元素必然也大于remain
,直接break
可减少递归次数,提升效率。- 回溯逻辑 :
path
记录当前组合,递归时通过remain - candidates[i]
更新剩余目标和,start
保持为i
实现元素可重复选取;递归返回后path.remove
撤销选择,继续尝试其他分支。- 结果收集 :当
remain == 0
时,将path
复制到新的ArrayList
再加入result
,避免后续path
变化影响已加入结果。