#leetcode#

#leetcode#

17.电话号码的字母组合

class Solution {

/**

* 生成电话号码对应的所有字母组合

* @param digits 输入的数字字符串(只包含2-9的数字)

* @return 所有可能的字母组合列表

*/

public List<String> letterCombinations(String digits) {

// 存储最终结果的列表

List<String> combinations = new ArrayList<String>();

// 边界条件:如果输入为空字符串,直接返回空列表

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

return combinations;

}

// 建立数字到对应字母的映射表,模拟手机按键布局

Map<Character, String> phoneMap = new HashMap<Character, String>() {{

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;

}

/**

* 回溯算法核心:递归生成所有可能的字母组合

* @param combinations 存储结果的列表

* @param phoneMap 数字到字母的映射表

* @param digits 输入的数字字符串

* @param index 当前处理的数字索引(从0开始)

* @param combination 用于构建当前组合的字符串缓冲

*/

public void backtrack(List<String> combinations, Map<Character, String> 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));

// 递归处理下一个数字(索引+1)

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

// 回溯:移除最后添加的字母,尝试下一个可能的字母

combination.deleteCharAt(index);

}

}

}

}

39.组合总和

class Solution {

/**

* 找出所有候选数中可以使数字和为目标值的组合(候选数可重复使用)

* @param candidates 候选数字数组(无重复元素,均为正整数)

* @param target 目标和

* @return 所有满足条件的组合列表

*/

public List<List<Integer>> combinationSum(int[] candidates, int target) {

// 存储最终所有满足条件的组合

List<List<Integer>> ans = new ArrayList<List<Integer>>();

// 用于临时存储当前正在构建的组合

List<Integer> combine = new ArrayList<Integer>();

// 调用深度优先搜索函数,从索引0开始处理

dfs(candidates, target, ans, combine, 0);

return ans;

}

/**

* 深度优先搜索(回溯法)寻找所有符合条件的组合

* @param candidates 候选数字数组

* @param target 剩余需要达成的目标和(初始为target,逐步递减)

* @param ans 存储结果的组合列表

* @param combine 当前正在构建的组合

* @param idx 当前处理的候选数索引(用于避免重复组合,保证组合内元素顺序与数组一致)

*/

public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) {

// 递归终止条件1:已经遍历完所有候选数,直接返回

if (idx == candidates.length) {

return;

}

// 递归终止条件2:剩余目标和为0,说明当前组合满足条件

if (target == 0) {

// 将当前组合的副本添加到结果列表(避免后续修改影响已存储的组合)

ans.add(new ArrayList<Integer>(combine));

return;

}

// 情况1:不选择当前索引的候选数,直接递归处理下一个索引

dfs(candidates, target, ans, combine, idx + 1);

// 情况2:选择当前索引的候选数(前提是当前数不超过剩余目标和)

if (target - candidates[idx] >= 0) {

// 将当前候选数加入临时组合

combine.add(candidates[idx]);

// 递归处理:剩余目标和减去当前数,索引不变(允许重复使用当前数)

dfs(candidates, target - candidates[idx], ans, combine, idx);

// 回溯:移除最后添加的数,恢复到选择前的状态,以便尝试其他组合

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

}

}

}

相关推荐
️停云️13 小时前
【滑动窗口与双指针】不定长滑动窗口
c++·算法·leetcode·剪枝·哈希
玖剹16 小时前
队列+宽搜(bfs)
数据结构·c++·算法·leetcode·宽度优先
有一个好名字18 小时前
力扣-从字符串中移除星号
java·算法·leetcode
萧瑟其中~18 小时前
二分算法模版——基础二分查找,左边界查找与右边界查找(Leetcode的二分查找、在排序数组中查找元素的第一个位置和最后一个位置)
数据结构·算法·leetcode
AlenTech18 小时前
208. 实现 Trie (前缀树) - 力扣(LeetCode)
leetcode
iAkuya18 小时前
(leetcode)力扣100 36二叉树的中序遍历(迭代递归)
算法·leetcode·职场和发展
wangwangmoon_light18 小时前
1.1 LeetCode总结(线性表)_枚举技巧
算法·leetcode·哈希算法
有一个好名字19 小时前
力扣-小行星碰撞
算法·leetcode·职场和发展
栈与堆20 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust