电话号码的字母组合java,[Leetcode][第17题][JAVA][电话号码的字母组合][回溯]

本文详细介绍了如何使用回溯法解决LeetCode第17题电话号码的字母组合问题,通过哈希表和数组两种方式演示了如何构建字母组合并进行递归操作。关键步骤包括初始化、回溯过程、以及如何检查完整解并添加到结果集中。
摘要由CSDN通过智能技术生成

[Leetcode][第17题][JAVA][电话号码的字母组合][回溯]

[Leetcode][第17题][JAVA][电话号码的字母组合][回溯]

【问题描述】[中等]

f2dca2f05f225f1e43726b6377388ff1.png

【解答思路】

用哈希表/数组存储每个数字对应的所有可能的字母,然后进行回溯操作。

回溯过程中维护一个字符串,表示已有的字母排列(如果未遍历完电话号码的所有数字,则已有的字母排列是不完整的)。该字符串初始为空。每次取电话号码的一位数字,从哈希表中获得该数字对应的所有可能的字母,并将其中的一个字母插入到已有的字母排列后面,然后继续处理电话号码的后一位数字,直到处理完电话号码中的所有数字,即得到一个完整的字母排列。然后进行回退操作,遍历其余的字母排列。

回溯算法用于寻找所有的可行解,如果发现一个解不可行,则会舍弃不可行的解。在这道题中,由于每个数字对应的每个字母都可能进入字母组合,因此不存在不可行的解,直接穷举所有的解即可。

507442528487a93aa4c97581322700f4.png

1. 回溯 哈希表

class Solution {

public List letterCombinations(String digits) {

List combinations = new ArrayList();

if (digits.length() == 0) {

return combinations;

}

Map phoneMap = new HashMap() {{

put('2', "abc");

put('3', "def");

put('4', "ghi");

put('5', "jkl");

put('6', "mno");

put('7', "pqrs");

put('8', "tuv");

put('9', "wxyz");

}};

backtrack(combinations, phoneMap, digits, 0, new StringBuffer());

return combinations;

}

public void backtrack(List combinations, Map phoneMap, String digits, int index, StringBuffer combination) {

if (index == digits.length()) {

combinations.add(combination.toString());

} else {

char digit = digits.charAt(index);

String letters = phoneMap.get(digit);

int lettersCount = letters.length();

for (int i = 0; i < lettersCount; i++) {

combination.append(letters.charAt(i));

backtrack(combinations, phoneMap, digits, index + 1, combination);

combination.deleteCharAt(index);

}

}

}

}

2. 回溯 数组存储

class Solution {

// 数字到号码的映射

private String[] map = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

// 路径

private StringBuilder sb = new StringBuilder();

// 结果集

private List res = new ArrayList<>();

public List letterCombinations(String digits) {

if(digits == null || digits.length() == 0) return res;

backtrack(digits,0);

return res;

}

// 回溯函数

private void backtrack(String digits,int index) {

if(sb.length() == digits.length()) {

res.add(sb.toString());

return;

}

String val = map[digits.charAt(index)-'2'];

for(char ch:val.toCharArray()) {

sb.append(ch);

backtrack(digits,index+1);

sb.deleteCharAt(sb.length()-1);

}

}

}

【总结】

1. 回溯递归通用模板,即用一个临时数组temp 来保存当前选出的子序列,使用cur 来表示当前位置的下标,在 dfs(cur, nums) 开始之前,[0,cur?1] 这个区间内的所有元素都已经被考虑过,而[cur,n] 这个区间内的元素还未被考虑。在执行 dfs(cur, nums) 时,我们考虑 cur 这个位置选或者不选,如果选择当前元素,那么把当前元素加入到temp 中,然后递归下一个位置,在递归结束后,应当把temp 的最后一个元素删除进行回溯;如果不选当前的元素,直接递归下一个位置。

List> ans = new ArrayList>();

List temp = new ArrayList();

public void dfs(int cur, int[] nums) {

if (cur == nums.length) {

// 判断是否合法,如果合法判断是否重复,将满足条件的加入答案

if (isValid() && notVisited()) {

ans.add(new ArrayList(temp));

}

return;

}

// 如果选择当前元素

temp.add(nums[cur]);

dfs(cur + 1, nums);

temp.remove(temp.size() - 1);

// 如果不选择当前元素

dfs(cur + 1, nums);

}

2.回溯相关题目

[Leetcode][第491题][JAVA][递增子序列][回溯][RK算法]

[Leetcode][第679题][JAVA][24点游戏][回溯][暴力]

[Leedcode][JAVA][第46题][全排列][回溯算法]

[Leetcode][第93题][JAVA][复原IP地址][剪枝][回溯]

[剑指offer]面试题第[38]题[JAVA][字符串的排列][回溯法]

[剑指offer][JAVA]面试题第[34]题[二叉树中和为某一值的路径][回溯]

[Leetcode][第17题][JAVA][电话号码的字母组合][回溯]

参考链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/solution/dian-hua-hao-ma-de-zi-mu-zu-he-by-leetcode-solutio/

[Leetcode][第17题][JAVA][电话号码的字母组合][回溯]相关教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是电话号码字母组合的 C++ 代码实现: ``` class Solution { public: vector<string> letterCombinations(string digits) { unordered_map<char, string> mapping = { {'2', "abc"}, {'3', "def"}, {'4', "ghi"}, {'5', "jkl"}, {'6', "mno"}, {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"} }; vector<string> res; if (digits.empty()) { return res; } string combination; backtrack(res, combination, digits, 0, mapping); return res; } void backtrack(vector<string>& res, string& combination, string& digits, int index, unordered_map<char, string>& mapping) { if (index == digits.size()) { res.push_back(combination); return; } for (char c : mapping[digits[index]]) { combination.push_back(c); backtrack(res, combination, digits, index + 1, mapping); combination.pop_back(); } } }; ``` 其中 `letterCombinations` 函数用来生成所有的字母组合,`backtrack` 函数用来进行回溯操作。在 `letterCombinations` 函数中,首先根据数字字符和字母的映射关系创建了一个 `unordered_map` 对象 `mapping`。然后定义了一个空字符串 `combination` 和一个空 vector `res` 来保存最终结果。最后调用了 `backtrack` 函数来生成所有的字母组合。在 `backtrack` 函数中,首先判断是否达到了数字字符串的末尾,如果是,则将当前的 `combination` 字符串保存到 `res` 中。否则,遍历当前数字字符所能表示的所有字母,依次加入到 `combination` 字符串中,然后递归调用 `backtrack` 函数,添加下一个数字字符所能表示的字母。递归完成后,需要将 `combination` 字符串还原到上一个状态,以便进行下一次回溯。最终返回 `res` 数组即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值