算法——LeetCode17. 电话号码的字母组合

17. 电话号码的字母组合

原题链接

题目:

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

输入:
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

题解1:递归(DFS)

主要流程:

  1. 首先判断特例,当输入为空,则直接返回空串
  2. 定义字符数组,用于存储数字对应的字母
  3. 定义递归函数 findCombination(String digits, int index, String s),digits为数字数组,index为搜索到digits的下标索引,也可以理解为递归深度,s为当前递归节点的字母组合字符串
  4. 递归函数编写:
  • 首先是递归终止条件,条件为index==digits.length,此时该节点为终止节点,将s添加到结果集并返回
  • 之后取出当前数字对应的所有字母,for循环向下搜索所有的组合。

注意: 递归函数 findCombination(String digits, int index, String s)中,如果最后一个参数使用StringBuilder或StringBuffer,那么在for循环中,必须加入 s.deleteCharAt(index);,这是由于String是不可变的,而StringBuilder或StringBuffer都是可变对象,在后面的递归中,会对该对象有修改,所以需要回溯,删除加入的字符,消除影响。因为StringBuilder传入的都是同一个对象,所以在递归完成之后必须撤回上一次的操作,需要删除上一次添加的字符。而String每次改变之后传入的都是不同的对象。故无需撤销操作。

    class Solution {
        private List<String> res=new ArrayList<>();
        String[] letterMaps={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        public List<String> letterCombinations(String digits) {
            //特例判断
            if (digits.length()==0||digits==null){
                return res;
            }
            //调用递归函数
            findCombination(digits,0,"");
            return res;
        }
        public void findCombination(String digits,int index,String s){
            //判断递归终止条件
            if(index==digits.length()){
                res.add(s);
                return;
            }
            //取出当前节点字母表
            char temp=digits.charAt(index);
            String letter=letterMaps[temp-'0'];
            //向下一层搜索
            for (int i = 0; i < letter.length(); i++) {
                findCombination(digits,index+1,s+letter.charAt(i));
            }
        }

    }

题解2:队列求法

主要思路:

主要流程:

  1. 首先判断特例,当输入为空,则直接返回空串
  2. 定义字符数组,用于存储数字对应的字母
  3. 遍历输入的数字数组,执行如下操作:
  • 取出当前数字对应的字母表,获取当前队列长度,遍历当前队列中的元素
  • 取出队头元素,再遍历当前字母表,将队头元素与当前字母表中所有字母依次拼接,拼接完成后再次入队
  1. 最终的队列即为结果集

代码如下:

    /**
     * 解法二:使用队列
     */
    class Solution {
        private List<String> res = new ArrayList<>();
        String[] letterMaps = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

        public List<String> letterCombinations(String digits) {
            //特例判断
            if (digits.length() == 0 || digits == null) {
                return res;
            }
            res.add("");
            //遍历数字,对每个数字做如下操作
            for (int i = 0; i < digits.length(); i++) {
                char index=digits.charAt(i);
                String letter=letterMaps[index-'0'];
                //获取当前队列长度
                int queueLength=res.size();
                for (int j = 0; j < queueLength; j++) {
                    //取出队头元素
                    String temp=res.remove(0);
                    //接下来对元素与每个字母拼接后再加入队列中
                    for (int k = 0; k < letter.length(); k++) {
                        res.add(temp+letter.charAt(k));
                    }
                }
            }
            return res;
        }


    }

题解参考:
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/solution/tong-su-yi-dong-dong-hua-yan-shi-17-dian-hua-hao-m/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值