日志|电话号码的字母组合|子集|回溯

局部截取_20251009_214710

解题思路:

回溯三问:

1.当前操作?枚举数组path[i]要填入的字母
2.子问题?构造字符串>= i 的部分
3.下一个子问题?构造>= i+1 的部分

对于本题

1.当前操作:枚举放入path当前i的字母 例如第2个数字对应的a b c
2.子问题:下一位置要放的字母的枚举 例如第3个数字对应的 d e f
3.下一个子问题:下一位置的下一位置的要放的字母的枚举

总结

例如输入[23]
先dfs(0),
本层 a 有 dfs(1),本层层有def,d有dfs(2)e有dfs(2)f有dfs(2)。又回到最上层dfs(0)
本层 b 有 dfs(1),本层层有def,d有dfs(2)e有dfs(2)f有dfs(2)。又回到最上层dfs(0)
本层 c 有 dfs(1),本层层有def,d有dfs(2)e有dfs(2)f有dfs(2)。又回到最上层dfs(0)
结束返回ans

点击查看代码
class Solution {
    private static final String[] MAPPING = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

    public List<String> letterCombinations(String digits) {
            int n = digits.length();
            if (n == 0) {
                return List.of();
            }

            List<String> ans = new ArrayList<>();
            char[] path = new char[n];
            dfs(0, ans, path, digits.toCharArray());
            return ans;
        }

        private void dfs(int i, List<String> ans, char[] path, char[] digits) {
            if (i == digits.length) {
                ans.add(new String(path));
                return;
            }
            String letters = MAPPING[digits[i] - '0'];
            for (char c : letters.toCharArray()) {
                path[i] = c;
                dfs(i + 1, ans, path, digits);
            }
        }


    
}

局部截取_20251009_230833

点击查看代码
class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        List<Integer> path =  ArrayList<>();
        dfs(0, nums, path, ans);
        return ans;
    }

    private void dfs(int i, int[] nums, List<Integer> path, List<List<Integer>> ans) {
        ans.add(new ArrayList<>(path)); // 复制 path
        for (int j = i; j < nums.length; j++) { // 枚举选择的数字
            path.add(nums[j]);
            dfs(j + 1, nums, path, ans);
            path.removeLast(); // path.remove(path.size() - 1);
        }
    }
}        

posted @ 2025-10-09 23:47  柳成荫y  阅读(7)  评论(0)    收藏  举报