• 【Letter Combinations of a Phone Number】cpp


    题目:

    Given a digit string, 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.

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

    Note:
    Although the above answer is in lexicographical order, your answer could be in any order you want.

    代码:

    class Solution {
    public:
        vector<string> letterCombinations(string digits) {
                vector<string> ret;
                if ( digits.empty() ) return ret; 
                map<int, string> digitLetters;
                digitLetters[0] = "";
                digitLetters[1] = "";
                digitLetters[2] = "abc";
                digitLetters[3] = "def";
                digitLetters[4] = "ghi";
                digitLetters[5] = "jkl";
                digitLetters[6] = "mno";
                digitLetters[7] = "pqrs";
                digitLetters[8] = "tuv";
                digitLetters[9] = "wxyz";
                vector<int> letterBegin(10,0);
                int index = 0;
                string tmp;
                Solution::combine(ret, tmp, index, digits, digitLetters, letterBegin);
                return ret;
        }
        static void combine(
            vector<string>& ret, 
            string& tmp, 
            int index, 
            string& digits, 
            map<int,string>& digitLetters, 
            vector<int>& letterBegin)
        {    
                if (index==digits.size())
                {
                    ret.push_back(tmp);
                    return;
                }
                int curr = digits[index]-'0';
                string letters = digitLetters[curr];
                for ( int i = 0; i < letters.size(); ++i )
                {
                    letterBegin[curr] = i;
                    tmp.push_back(letters[i]);
                    Solution::combine(ret, tmp, index+1, digits, digitLetters, letterBegin);
                    tmp.erase(tmp.end()-1);
                }
        }
    };

    tips:

    上述的代码是AC的。思路也就是常规dfs的思路:

    1. 终止条件是层级到了digits的长度

    2. 每一层递归相当于根据该位置的数字选一个字母

    但是,个人感觉这道题的题干要求没说清楚;既然是letter combinations,而不是letter permutation,那么“ac”和“ca”就应该算一个combination,但是OJ之后发现默认“ac”和“ca”算两个。加入“ac”和“ca”算一个,有没有解法呢?代码如下:

    class Solution {
    public:
        vector<string> letterCombinations(string digits) {
                vector<string> ret;
                if ( digits.empty() ) return ret; 
                map<int, string> digitLetters;
                digitLetters[0] = "";
                digitLetters[1] = "";
                digitLetters[2] = "abc";
                digitLetters[3] = "def";
                digitLetters[4] = "ghi";
                digitLetters[5] = "jkl";
                digitLetters[6] = "mno";
                digitLetters[7] = "pqrs";
                digitLetters[8] = "tuv";
                digitLetters[9] = "wxyz";
                vector<int> letterBegin(10,0);
                int index = 0;
                string tmp;
                Solution::combine(ret, tmp, index, digits, digitLetters, letterBegin);
                return ret;
        }
        static void combine(
            vector<string>& ret, 
            string& tmp, 
            int index, 
            string& digits, 
            map<int,string>& digitLetters, 
            vector<int>& letterBegin)
        {    
                if (index==digits.size())
                {
                    ret.push_back(tmp);
                    return;
                }
                int curr = digits[index]-'0';
                string letters = digitLetters[curr];
                for ( int i = letterBegin[curr]; i < letters.size(); ++i )
                {
                    letterBegin[curr] = i;
                    tmp.push_back(letters[i]);
                    Solution::combine(ret, tmp, index+1, digits, digitLetters, letterBegin);
                    tmp.erase(tmp.end()-1);
                }
        }
    };

    tips:

    多维护一个letterBegin的数组,标记“当前的组合中,某个数字对应的字母序列中应该从第几个字母开始取”。

    如果输入是“22”,那么给出的解集就是:

    aa

    ab

    ac

    bb

    bc

    cc

    从这个例子可以看出来,算法的原理就是维护某一个数字对应字母序列:如果数字重复出现,那么对应的字母要保证字典序递增,这样就不会用重复的。

    可惜题目并不是这么要求的。

    ===============================================

    既然题目要求简单了,则再追求一个迭代的解法。AC的代码如下:

    class Solution {
    public:
        vector<string> letterCombinations(string digits) {
                vector<string> ret;
                if (digits.empty()) return ret;
                ret.push_back("");
                map<int, string> digitLetters;
                digitLetters[2] = "abc";
                digitLetters[3] = "def";
                digitLetters[4] = "ghi";
                digitLetters[5] = "jkl";
                digitLetters[6] = "mno";
                digitLetters[7] = "pqrs";
                digitLetters[8] = "tuv";
                digitLetters[9] = "wxyz";
                for ( size_t i = 0; i < digits.size(); ++i )
                {
                    int curr = digits[i]-'0';
                    string letters = digitLetters.find(curr)==digitLetters.end() ? "" : digitLetters[curr];
                    vector<string> tmp = ret;
                    ret.clear();
                    for ( size_t j = 0; j < tmp.size(); ++j )
                    {
                        for ( size_t k = 0; k < letters.size(); ++k )
                        {
                            string ori = tmp[j];
                            ori += letters[k];
                            ret.push_back(ori);
                        }
                    }
                }
                return ret;
        }
    };

    完毕。

    ======================================

    第二次过这道题,用dfs过的。注意如果原来的digits==""返回的也是空。

    class Solution {
    public:
            vector<string> letterCombinations(string digits)
            {    
                map<char, string> digit_letters;
                digit_letters['2'] = "abc";
                digit_letters['3'] = "def";
                digit_letters['4'] = "ghi";
                digit_letters['5'] = "jkl";
                digit_letters['6'] = "mno";
                digit_letters['7'] = "pqrs";
                digit_letters['8'] = "tuv";
                digit_letters['9'] = "wxyz";
                vector<string> ret;
                if ( digits=="" ) return ret;
                vector<char> tmp;
                Solution::dfs(ret, digits, tmp, digit_letters); 
                return ret;
            }
            static void dfs(
                vector<string>& ret, 
                string digits, 
                vector<char>& tmp,
                map<char,string>& digit_letters)
            {
                if ( tmp.size()==digits.size() )
                {
                    ret.push_back(string(tmp.begin(),tmp.end()));
                    return;
                }
                int index = tmp.size();
                for ( int i=0; i<digit_letters[digits[index]].size(); ++i )
                {
                    tmp.push_back(digit_letters[digits[index]][i]);
                    Solution::dfs(ret, digits, tmp, digit_letters);
                    tmp.pop_back();
                }
            }
    };
  • 相关阅读:
    收藏一个超牛的css平滑移动 jquery插件
    惊艳到不行啊,html5真的牛逼
    推荐可以代替Visio的HTML开发的作图工具:ProcessOn
    struts标签 展示富文本时遇到的问题。
    ECharts 大数据时代,重新定义数据图表的时候到了
    Xtrareport 实现交叉表数据重复显示的问题
    【转】ASP.NET程序中常用的三十三种代码
    How to find the Report Data tab in SSRS after closing it
    分享经验, 技术探讨, 共同学习.
    Reporting Services 在WIN7和2008下出现“授予的权限不足,无法执行此操作。 (rsAccessDenied)”的解决办法
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4522163.html
Copyright © 2020-2023  润新知