leetcode 17 电话号码的字母组合(Letter Combinations of a Phone Number)

题目

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.

A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

Example:

Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

思路

题目的本质是多维数组展开为一维数组,每个数字对应的字符串的长度就是该维的大小,以234为例,3个数字对应的字符串长度都为3,因此三位数组每一维的大小就是3,我们要做的就是把这个3维数组展开为一维,将一维数组索引转换为3维。

一维数组索引三维数组索引
00,0,0
10,0,1
80,2,2
91,0,0
262,2,2

代码

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        map<char, string> int2str;
        buildInt2Str(int2str);
        
        vector<int> multis;
        int multi = 1;
        for (int i = digits.size() - 2; i >= 0; --i) {
            multi *= int2str[digits[i + 1]].size();
            multis.insert(multis.begin(), multi);
        }
        
        vector<string> res;
        for (int i = 0; i < multi * int2str[digits[0]].size(); ++i) {
            string s("");
            for (int j = 0; j < digits.size() - 1; ++j) {
                int idx = i / multis[j];
                if (j > 0) {
                    idx = (i % multis[j - 1]) / multis[j];
                }
                s += int2str[digits[j]][idx];
            }
            string last = int2str[digits[digits.size() - 1]];
            s += last[i % last.size()];
            res.push_back(s);
        }
        
        return res;
    }
private:
    void buildInt2Str(map<char, string> &int2str) {
        int2str.insert(pair<char, string>('2', "abc"));
        int2str.insert(pair<char, string>('3', "def"));
        int2str.insert(pair<char, string>('4', "ghi"));
        int2str.insert(pair<char, string>('5', "jkl"));
        int2str.insert(pair<char, string>('6', "mno"));
        int2str.insert(pair<char, string>('7', "pqrs"));
        int2str.insert(pair<char, string>('8', "tuv"));
        int2str.insert(pair<char, string>('9', "wxyz"));
    }
};

构造数字到字符串的映射表

        map<char, string> int2str;
        buildInt2Str(int2str);

获取每一维数组大小

        vector<int> multis;
        int multi = 1;
        for (int i = digits.size() - 2; i >= 0; --i) {
            multi *= int2str[digits[i + 1]].size();
            multis.insert(multis.begin(), multi);
        }

以234数组为例,第一维大小为12=3*4,第二维大小为4,第三维直接取下标

根据一维下标获取三维数组下标

        vector<string> res;
        for (int i = 0; i < multi * int2str[digits[0]].size(); ++i) {
            string s("");
            for (int j = 0; j < digits.size() - 1; ++j) {
                int idx = i / multis[j];
                if (j > 0) {
                    idx = (i % multis[j - 1]) / multis[j];
                }
                s += int2str[digits[j]][idx];
            }
            string last = int2str[digits[digits.size() - 1]];
            s += last[i % last.size()];
            res.push_back(s);
        }

注意,在获取第1~(n-1)维的下标时,需要先对前一维的数组大小取余:

                if (j > 0) {
                    idx = (i % multis[j - 1]) / multis[j];
                }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值