【算法】17. 电话号码的字母组合(多语言实现)

简介: 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

17. 电话号码的字母组合:

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

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

样例 1:

输入:
    digits = "23"

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

样例 2:

输入:
    digits = ""

输出:
    []

样例 3:

输入:
    digits = "2"

输出:
    ["a","b","c"]

提示:

  • 0 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

分析

  • 面对这道算法题目,二当家的陷入了沉思。
  • 仔细看了看,好像没有什么特别的技巧。
  • 递归套娃大法比较直观,dfs,回溯。
  • 细节的地方在于字符串拼接,有些语言的字符串是不可变的,在字符串拼接上有可以优化的点。

题解

rust

const PHONE_MAP: &[&[char]] = &[&[], &[], &['a', 'b', 'c'], &['d', 'e', 'f'], &['g', 'h', 'i'], &['j', 'k', 'l'], &['m', 'n', 'o'], &['p', 'q', 'r', 's'], &['t', 'u', 'v'], &['w', 'x', 'y', 'z']];

impl Solution {
   
   
    pub fn letter_combinations(digits: String) -> Vec<String> {
   
   
        fn backtrack(ans: &mut Vec<String>, digits: &[u8], index: usize, buf: &mut Vec<u8>) {
   
   
            if index == digits.len() {
   
   
                ans.push(String::from_utf8(buf.clone()).unwrap());
            } else {
   
   
                let digit = (digits[index] - '0' as u8) as usize;
                PHONE_MAP[digit].iter().for_each(|c| {
   
   
                    buf[index] = *c as u8;
                    backtrack(ans, digits, index + 1, buf);
                });
            }
        }

        let mut ans = Vec::new();
        if digits.len() > 0 {
   
   
            backtrack(&mut ans, digits.as_bytes(), 0, &mut vec![0; digits.len()]);
        }
        ans
    }
}

go

var phoneMap [][]byte = [][]byte{
   
   {
   
   }, {
   
   }, {
   
   'a', 'b', 'c'}, {
   
   'd', 'e', 'f'}, {
   
   'g', 'h', 'i'}, {
   
   'j', 'k', 'l'}, {
   
   'm', 'n', 'o'}, {
   
   'p', 'q', 'r', 's'}, {
   
   't', 'u', 'v'}, {
   
   'w', 'x', 'y', 'z'}}

func letterCombinations(digits string) []string {
   
   
    var ans []string

    var backtrack func(int, []byte)
    backtrack = func(index int, buf []byte) {
   
   
        if index == len(digits) {
   
   
            ans = append(ans, string(buf))
        } else {
   
   
            digit := digits[index]
            for _, c := range phoneMap[digit-'0'] {
   
   
                buf[index] = c
                backtrack(index+1, buf)
            }
        }
    }

    if len(digits) > 0 {
   
   
        backtrack(0, make([]byte, len(digits)))
    }

    return ans
}

c++

class Solution {
   
   
private:
    unordered_map<char, string> phoneMap{
   
   
            {
   
   '2', "abc"},
            {
   
   '3', "def"},
            {
   
   '4', "ghi"},
            {
   
   '5', "jkl"},
            {
   
   '6', "mno"},
            {
   
   '7', "pqrs"},
            {
   
   '8', "tuv"},
            {
   
   '9', "wxyz"}
    };

    void backtrack(vector<string> &ans, const string &digits, int index, string &buf) {
   
   
        if (index == digits.length()) {
   
   
            ans.emplace_back(buf);
        } else {
   
   
            char digit = digits[index];
            for (const char &c: phoneMap.at(digit)) {
   
   
                buf.push_back(c);
                backtrack(ans, digits, index + 1, buf);
                buf.pop_back();
            }
        }
    }

public:
    vector<string> letterCombinations(string digits) {
   
   
        vector<string> ans;

        if (digits.size() > 0) {
   
   
            string buf;
            backtrack(ans, digits, 0, buf);
        }

        return ans;
    }
};

java

class Solution {
   
   
    private static final char[][] PHONE_MAP = new char[][]{
   
   {
   
   },{
   
   },{
   
   'a','b','c'},{
   
   'd','e','f'},{
   
   'g','h','i'},{
   
   'j','k','l'},{
   
   'm','n','o'},{
   
   'p','q','r','s'},{
   
   't','u','v'},{
   
   'w','x','y','z'}};

    public List<String> letterCombinations(String digits) {
   
   
        List<String> ans = new ArrayList<>();

        if (digits.length() > 0) {
   
   
            this.backtrack(ans, digits, 0, new char[digits.length()]);
        }

        return ans;
    }

    private void backtrack(List<String> ans, String digits, int index, char[] buf) {
   
   
        if (index == digits.length()) {
   
   
            ans.add(new String(buf));
        } else {
   
   
            int digit = digits.charAt(index) - '0';
            for (char c : PHONE_MAP[digit]) {
   
   
                buf[index] = c;
                backtrack(ans, digits, index + 1, buf);
            }
        }
    }
}

typescript

const phoneMap = {
   
   
    2: 'abc',
    3: 'def',
    4: 'ghi',
    5: 'jkl',
    6: 'mno',
    7: 'pqrs',
    8: 'tuv',
    9: 'wxyz',
};

function letterCombinations(digits: string): string[] {
   
   
    let ans = [];

    const backtrack = function (index: number, buf: string) {
   
   
        if (index == digits.length) {
   
   
            ans.push(buf);
        } else {
   
   
            const digit = digits[index];
            for (const c of phoneMap[digit]) {
   
   
                backtrack(index + 1, buf + c);
            }
        }
    };

    if (digits.length > 0) {
   
   
        backtrack(0, "");
    }

    return ans;
};

python

class Solution:
    PHONE_MAP = {
   
   
        "2": "abc",
        "3": "def",
        "4": "ghi",
        "5": "jkl",
        "6": "mno",
        "7": "pqrs",
        "8": "tuv",
        "9": "wxyz",
    }

    def letterCombinations(self, digits: str) -> List[str]:
        def backtrack(index: int):
            if index == len(digits):
                ans.append("".join(buf))
            else:
                digit = digits[index]
                for letter in Solution.PHONE_MAP[digit]:
                    buf.append(letter)
                    backtrack(index + 1)
                    buf.pop()

        ans = list()
        buf = list()
        if len(digits) > 0:
            backtrack(0)
        return ans

非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://developer.aliyun.com/profile/sqd6avc7qgj7y 博客原创~


相关文章
|
2月前
|
自然语言处理 Rust 算法
【算法】13. 罗马数字转整数(多语言实现)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 | 字符 | 数值 | |--|--| | I | 1 | | V | 5 | | X | 10 | | L | 50 | | C | 100 | | D | 500 | | M | 1000 | 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1
【算法】13. 罗马数字转整数(多语言实现)
|
29天前
|
算法 自然语言处理 Rust
【算法】16. 最接近的三数之和(多语言实现)
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。
|
19天前
|
算法
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
【经典LeetCode算法题目专栏分类】【第11期】递归问题:字母大小写全排列、括号生成
|
19天前
|
算法
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串
|
27天前
|
存储 算法 Java
【经典算法】LeetCode 1170:比较字符串最小字母出现频次(Java/C/Python3实现含注释说明,中等)
【经典算法】LeetCode 1170:比较字符串最小字母出现频次(Java/C/Python3实现含注释说明,中等)
16 0
|
2月前
|
自然语言处理 Rust 算法
【算法】15. 三数之和(多语言实现)
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。
|
2月前
|
自然语言处理 Rust 算法
【算法】14. 最长公共前缀(多语言实现)
编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。
|
2月前
|
自然语言处理 Rust 算法
【算法】11. 盛最多水的容器(多语言实现)
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明: 你不能倾斜容器。
【算法】11. 盛最多水的容器(多语言实现)
|
2月前
|
自然语言处理 Rust 算法
【算法】12. 整数转罗马数字(多语言实现)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而
|
2月前
|
算法 索引
算法编程(二十):仅仅反转字母
算法编程(二十):仅仅反转字母
32 0