17. 电话号码的字母组合(Java)

题目描述

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

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
在这里插入图片描述

示例:

输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。


解法一:队列

过程

  • “”
  • “a” “b” “c”
  • “b” “c” “ad”,“ae”,“af”
  • “c” “ad”,“ae”,“af” “bd” “be” “bf”
  • “ad”,“ae”,“af” “bd” “be” “bf” “cd” “ce” “cf”

思路

  • 当列表的首位置长度list.peek().length()等于当前要遍历的digits长度i,则弹出首位置,重复加上i+1的字符。
    在这里插入图片描述
class Solution {
    public List<String> letterCombinations(String digits) {
        //利用队列形式的链表,因为要用到LinkedList特有的方法
        LinkedList<String> list=new LinkedList();
        String[] s={"0","1","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        if(digits.length()==0)  return list;
        //先加入预设空值,用于取出
        list.add("");
        for(int i=0;i<digits.length();i++){
            int x=Character.getNumericValue(digits.charAt(i));
            //若链表头节点长度跟i相同,则取出加上新值再存进去
            while(list.peek().length()==i){
                String str=list.remove();
                for(char c:s[x].toCharArray()){
                    list.add(str+c);
                }
            }
        }
        return list;
    }
}

在这里插入图片描述


解法二:回溯

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odJuHQ6G-1585151534325)(D:\leetcode\图片\17. 电话号码的字母组合\1.jpg)]

在这里插入图片描述

class Solution {
    String[] s={"0","1","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    List<String> res;
    public List<String> letterCombinations(String digits) {
        res=new ArrayList();
        if(digits.length()==0) return res;
        dfs(digits,"",0);
        return res;
    }
    public void dfs(String digits,String letter,int index){
        if(index==digits.length()){
            res.add(letter);
            return;
        }
        char c=digits.charAt(index);
        int x=c-'0';
        int len=s[x].length();
        for(int i=0;i<len;i++){
            dfs(digits,letter+s[x].charAt(i),index+1);
        }
    }
}

在这里插入图片描述


扩展知识点

关于多态
  • T1 a= new T1();表示创建一个新的T1对象.
    T2 b= new T1();这种多用在接口类与实现类之间或子类与父类间
    父 f= new 子();
  • 在接口中使用时:T2应该是一个接口类,T1为T2的实现类。
    成员变量、构造方法、静态方法看父类。成员方法:编译看左边,运行看右边(被重写覆盖
    在子类与父类关系时:T2为父类,T1为T2的子类。
  • 多态的弊端,不能使用子类特有的功能
    • List list=new LinkedList() 就不能使用LinkedList的方法了,只能通过向下转型,LinkedList ans=(LinkedList) list;
    • 当然最好的方法还是直接声明子类
    • LinkedList list=new LinkedList();
关于返回类型

返回类型是父类,可以返回子类吗?

  • 会将子类强制转换为父类。
字符串中的数字字符转换为整型

方法一:

int c=getNemericValue(s.charAt(i));

方法二:

char c=s.charAt(i);
int =c-'0';
该题回溯方法总结
  • 需要三个参数,一个是输入的子串,二是用于暂存的子串,三是记录当前追溯到输入子串的索引。

  • 终止条件:当index长度等于digits长度,将当前暂存的子串存入,返回。

  • 用for循环依次访问当前输入子串索引所对应的值。

    • 加入该值,index+1,递归访问。(深搜)
  • 该题目常规回溯写法循环里可以分三步

class Solution {
    String[] s={"0","1","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    List<String> res;
    public List<String> letterCombinations(String digits) {
        res=new ArrayList();
        if(digits.length()==0) return res;
        dfs(digits,"",0);
        return res;
    }
    public void dfs(String digits,String letter,int index){
        if(index==digits.length()){
            res.add(letter);
            return;
        }
        char c=digits.charAt(index);
        int x=c-'0';
        int len=s[x].length();
        //是否从0开始取决于能不能重复。
        for(int i=0;i<len;i++){
            //等同于dfs(digits,letter+s[x].charAt(i),index+1);
            letter=letter+s[x].charAt(i);
            dfs(digits,letter,index+1);
            letter=letter.substring(0,letter.length()-1);
        }
    }
}

在这里插入图片描述

发布了38 篇原创文章 · 获赞 0 · 访问量 521
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览