leetcode-17. Letter Combinations of a Phone Number

题目类型:

字符串

题意:

类似电话键盘,给出一个由数字组成的字符串,输出对应字母的所有组合。

image

例子:

Input:Digit string “23”

Output: [“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].

我的思路:递归

22%

  1. 前两个任意组合,结果再与第三个组合,结果再与第四个组合…以此类推。
  2. 键盘数字对应的字母可以存到数组,也可以存到hashMap

步骤:

  1. 将数字对应的字母列表存到hashMap
  2. 递归函数的参数:list1, list2,当前已经计算到的digit下标cur,digit长度, map)
  3. 将digit[0]和digit[1]对应的列表采用双层循环计算出组合存入新的列表list,若++cur不超出digit下标,那么传入list和map.get(digit[++cur]),递归计算。
class Solution {
    public List<String> letterCombinations(String digits) {
        if (digits == null || digits.equals("")) {
            return new ArrayList<>();
        }
        Map<Integer, List<String>> map = new HashMap<>();
        map.put(2, Arrays.asList("a", "b", "c"));
        map.put(3, Arrays.asList("d", "e", "f"));
        map.put(4, Arrays.asList("g", "h", "i"));
        map.put(5, Arrays.asList("j", "k", "l"));
        map.put(6, Arrays.asList("m", "n", "o"));
        map.put(7, Arrays.asList("p", "q", "r", "s"));
        map.put(8, Arrays.asList("t", "u", "v"));
        map.put(9, Arrays.asList("w", "x", "y", "z"));
        char[] digit = digits.toCharArray();
        int len = digit.length;
        if (len == 1) {
            return map.get(digit[0] - '0');
        }
        return calComponent(map.get(digit[0] - '0'), map.get(digit[1] - '0'), 1, len, map, digit);

    }

    private List<String> calComponent(List<String> list1, List<String> list2, int cur, int len, Map<Integer, List<String>> map, char[] digit) {
        List<String> list = new ArrayList<>();
        for (String s1 : list1) {
            for (String s2 : list2) {
                list.add(s1 + s2);
            }
        }
        if (++cur < len) {
            return calComponent(list, map.get(digit[cur] - '0'), cur, len, map, digit);
        }
        return list;
    }
}

方法二:改进递归

递归参数:给出的数字组合digits,结果列表res,当前的字母组合cur,当前遍历的digits位置i
1. 如果i为digits.length(),证明digits便利完毕,那么将当前组合cur加入res,return
2. 否则,需要将本层的字母叠加上:
- 得到本层数字对应的字母表
- 对于每一个字母,与之前的cur组合加上后传入新的递归

  public List<String> letterCombinations(String digits) {
      List<String> res = new ArrayList<>();
      if (digits == null || digits.equals("")) return res; 
      String[] letters = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
      calComponent(digits, res, "", 0, letters);
      return res;
}

    private void calComponent(String digits, List<String> res, String cur, int i, String[] letters) {
        // TODO Auto-generated method stub
        if (i == digits.length()) {
            res.add(cur);
            return;
        }
        String str = letters[digits.charAt(i) - '0'];
        for (char c : str.toCharArray()) {
            calComponent(digits, res, cur + c, i + 1, letters);
        }
    }

递归时注意,要传递cur+c,因为如此传递,才会在下一层得到cur+c,且返回到本层时 cur依然维持原有的cur。若改变cur=cur+c,那么cur全改变。

方法三:队列

  1. (类似于BFS)假设当前遍历到digits第i个字符,将队列中长度为i-1的出队,循环加上当前字符对应的字母后入队列。
  2. 因为结果要求输出List,所以定义队列不能用传统的Queue res = new LinkedList<>(); 而需要用==LinkedList res = 。。。来定义。==
class Solution {
    //方法三:队列
    public List<String> letterCombinations(String digits) {
        LinkedList<String> res = new LinkedList<>();
        if (digits.length() == 0) {
            return res;
        }
        String[] letters = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        res.add("");
        for (int i = 0; i < digits.length(); i++) {
            int cur = digits.charAt(i) - '0';
            while (res.peek().length() == i) {//因为i下标是当前位置-1
                String temp = res.remove();
                for (char c : letters[cur].toCharArray()) {
                    res.offer(temp + c);
                }
            }
        }
        return res;

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值