返回
拨开迷雾见彩虹——【LeetCode】电话号码的字母组合Java题解
后端
2023-12-02 15:45:52
【LeetCode】电话号码的字母组合Java题解
问题
给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。
给出数字到字母的映射如下(与电话按键对应):
2 -> "abc"
3 -> "def"
4 -> "ghi"
5 -> "jkl"
6 -> "mno"
7 -> "pqrs"
8 -> "tuv"
9 -> "wxyz"
算法分析
为了解决本问题,我们将采用递归和回溯两种算法进行详细的讲解和示例分析。
递归算法
递归是一种经典的算法设计范式,其核心思想在于将一个问题拆解成若干个规模更小的相同问题,依次解决这些小问题直至最终得到原问题的解。对于本问题,我们可以将电话号码中的每个数字作为递归函数的一个参数,并根据该数字对应的字母进行递归调用,最终得到所有可能的字母组合。
递归算法Java实现
import java.util.ArrayList;
import java.util.List;
class Solution {
private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
public List<String> letterCombinations(String digits) {
if (digits == null || digits.isEmpty()) {
return new ArrayList<>();
}
List<String> result = new ArrayList<>();
letterCombinationsHelper(digits, 0, new StringBuilder(), result);
return result;
}
private void letterCombinationsHelper(String digits, int index, StringBuilder sb, List<String> result) {
if (index == digits.length()) {
result.add(sb.toString());
return;
}
int num = digits.charAt(index) - '0';
String letters = KEYS[num];
for (int i = 0; i < letters.length(); i++) {
sb.append(letters.charAt(i));
letterCombinationsHelper(digits, index + 1, sb, result);
sb.deleteCharAt(sb.length() - 1);
}
}
}
回溯算法
回溯是一种与递归类似的算法设计范式,但其着重于在搜索过程中根据一定条件舍弃某些路径,从而提高算法的效率。对于本问题,我们可以通过回溯算法来减少不必要的重复计算,从而降低时间复杂度。
回溯算法Java实现
import java.util.ArrayList;
import java.util.List;
class Solution {
private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
public List<String> letterCombinations(String digits) {
if (digits == null || digits.isEmpty()) {
return new ArrayList<>();
}
List<String> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
backtrack(digits, 0, sb, result);
return result;
}
private void backtrack(String digits, int index, StringBuilder sb, List<String> result) {
if (index == digits.length()) {
result.add(sb.toString());
return;
}
int num = digits.charAt(index) - '0';
String letters = KEYS[num];
for (int i = 0; i < letters.length(); i++) {
sb.append(letters.charAt(i));
backtrack(digits, index + 1, sb, result);
sb.deleteCharAt(sb.length() - 1);
}
}
}
复杂度分析
对于本问题,递归和回溯算法的时间复杂度均为O(3^n * 4^m),其中n和m分别代表电话号码中数字2-6和数字7-9的个数。空间复杂度为O(n),其中n为电话号码中的数字个数。
总结
在本文中,我们详细介绍了递归和回溯算法在解决【电话号码的字母组合】问题中的应用,并提供了详细的Java实现代码。读者可以根据自己的需求选择合适的算法来解决该问题,并进一步拓展和应用所学的知识。