电话号码的排列组合​(初入搜索)

  持续刷题第7天 !

       今天我们继续刷Leetcode 热题 HOT 100,日复一日,相信自己,一定会有进步。如果一个人刷题太孤独了,欢迎加群每日一题算法群,让我们大家一起监督,一起成长。

Leetcode - 17.电话号码的排列组合

题目描述:

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

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

注意:答案中不可以包含重复的三元组。

示例:

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

解题思路:

怎么解呢?

    这道题主要考察的还是搜索,由于一个字母对应的是多种方案,那么多个字母组合,相当于是由各自方案的组合,你这个例子23为例,那么232中选一个字母,在2中选一个字母,这样的话就组成了一种可能的方式,由于每个数字代表的,字母个数为三个或四个,那么相当于组合后的方式是等同于字母个数相乘。
    例如23,这是3个字母和3个字母相乘,一共是九种方案。

编辑的时候想到: 状态动态规划,就是利用二进制数去代表每一个可以选的方式,假设现在是二代表的是ABC三个字母,那么我用100表示选的是a,表示选的第一个字母,010代表选b,001代表选c.有那么一点状态压缩的意思,后面说到状态DP会详细提到,这里就不用啦。

    这道题目其实是可以采用深度优先搜索中不用回溯的做法,也其实是深度优先搜索的入门题,也就是说,当前的选择不会因为上一选择而所受到影响,因为每次他要选字母都可以选。


    后面我们会讲到,由于上一种上一个数字选,那么这个数字不能选,所以需要有一种回溯的做法,可以参考全排列1,全排列2这两道题目。

那么我们在这里采用广度优先搜索的方式,利用队列即可完成。

  1. 用哈希表把每个数字对应的字母做个映射

  2. 然后每次取到这个数字的时候,把所有的字母状态拿出来

  3. 把队列中的元素取出,依次进行加工,然后再把加工后的元素插入

  4. 把之前上一个字母加工的元素弹出,让队列中永远都保存新鲜的加工元素

  5. 最后队列里保存的都是最后一层,已经全部加工完的元素

class Solution {
  Map<String, String> phone = new HashMap<String, 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");
  }};
  private List<String> output = new LinkedList<>();
  public List<String> letterCombinations(String digits) {
    if(digits.length()==0)//长度为0 返回
        return output;
    output.add("");//初始化
    for(int i=0;i<digits.length();i++){//遍历每一个数字
        int N=output.size();//得到队列长度,需要一次弹出往后面加东西
        while(N-->0){
            String tp=output.get(0);//得到队首
            String state=phone.get(String.valueOf(digits.charAt(i)));//得到下一层要的加的字母
            for(int k=0;k<state.length();k++)//遍历所有字母,往队首加上去 然后加入队列中
                output.add(tp+state.charAt(k));
            output.remove(0);//将队首弹出,意味着这个加工完成
        }
    }
    return output;

  }
}

往期回顾

LeetCode day 1 题号1、2(两数之和,两数相加)

LeetCode day 2 题号 3、4 (最长无重复子串,两个有序数组的中位数)

LeetCode day3 题号5 (最长回文子串)

LeetCode day 4  10.正则匹配

LeetCode day 5 盛最多水的容器(双指针)

LeetCode day 6 三数之和=两数之和plus

扫码加入我们

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值