LeetCode(17) Letter Combinations of a Phone Number

183 篇文章 0 订阅
47 篇文章 36 订阅

题目如下,输入一串数字,根据电话键盘布局输出此数字可能代表的字母组合。

Given a digit string, return all possible letter combinations that the number could represent.
Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

第一次做这道题目的时候,比较笨,由于2这个key对应了 a, b, c这三个value,所以我尝试着使用了multimap,这个关联容器在key-value为一对多关系的时候使用。对于multi_map的使用比较新鲜,平时几乎不用。这道题目主要参考了C++ Primer中第10章对于multi_set的讲解。

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
using namespace std;

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        int len_src=(int)digits.length();
        vector<string> res;
        if(len_src==0){
            res.push_back("");
            return res;
        }
        multimap<string,string> digi_str_multi_map;
        const string str_arr[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        const string int_arr[10]={"0","1","2","3","4","5","6","7","8","9"};
        for(int i=0;i<10;i++){
            for(int j=0;j<str_arr[i].length();j++){
                string c_tmp=str_arr[i].substr(j,1);
              digi_str_multi_map.insert(pair<string, string>(int_arr[i],c_tmp));
            }
        }
        typedef multimap<string,string>::iterator mm_it_type;
        set<string> res_set;
        set<string>::iterator res_set_it; //1324
        for(int i=0;i<len_src;i++){
            set<string> tmp_res_set;
            if(res_set.empty()) {
                string search_item(digits.substr(i,1));
                pair<mm_it_type,mm_it_type> pos=digi_str_multi_map.equal_range(search_item);
                while(pos.first!=pos.second) {
                    res_set.insert(pos.first->second);
//                    std::cout<<"1-1: "<<pos.first->second<<", search_item="<<search_item<<std::endl;
                    ++pos.first;
                }
                continue;
            }else{
                string search_item(digits.substr(i,1));
                pair<mm_it_type,mm_it_type> pos=digi_str_multi_map.equal_range(search_item);
                while(pos.first!=pos.second) {
                    for(res_set_it=res_set.begin();res_set_it!=res_set.end();res_set_it++) {
                        string tmp=*res_set_it+pos.first->second;
//                        std::cout<<"2-1: "<<tmp<<", search_item="<<search_item<<std::endl;
                        tmp_res_set.insert(tmp);
                    }
                    ++pos.first;
                }
            }
            res_set.clear();
            res_set=tmp_res_set;
        }
        for(set<string>::const_iterator it=res_set.begin();it!=res_set.end();it++)
            res.push_back(*it);
        return res;
    
    }
};


后来,重新改了改代码,用普通的数据结构完成了迭代版,也写了递归版。

update1 使用3层vector的嵌套完成迭代版

//迭代版,使用vector的3层嵌套
    vector<string> letterCombinations(string digits) {
        vector<string> res;
        res.push_back("");
        if(digits.length()==0)
            return res;
        const string str_arr[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        //        const int int_arr[10]={0,1,2,3,4,5,6,7,8,9};
        vector<vector<string>> mapping_vec;
        for(int i=0;i<10;i++){
            vector<string> tmp;
            for(int j=0;j<str_arr[i].size();j++){
                string tmp_str(str_arr[i]);
                tmp.push_back(tmp_str.substr(j,1));
            }
            mapping_vec.push_back(tmp);
        }
        vector<string> tmp_res;
        for(int i=0;i<digits.length();i++){
            for(int j=0;j<res.size();j++){
                string pre_str=res[j];
                for(int k=0;k<mapping_vec[atoi(digits.substr(i,1).c_str())].size();k++){
                    string cur_str=pre_str+mapping_vec[atoi(digits.substr(i,1).c_str())][k];
                    tmp_res.push_back(cur_str);
                }
            }
            res.swap(tmp_res);
            tmp_res.clear();
        }
        return res;
    }

update2 递归版

//递归版
    vector<string> letterCombinations2(string digits) {
        vector<string> res;
        if(digits.length()==0){
            res.push_back("");
            return res;
        }
        const string str_arr[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
//        const int int_arr[10]={0,1,2,3,4,5,6,7,8,9};
        vector<vector<string>> mapping_vec;
        for(int i=0;i<10;i++){
            vector<string> tmp;
            for(int j=0;j<str_arr[i].size();j++){
                string tmp_str(str_arr[i]);
                tmp.push_back(tmp_str.substr(j,1));
            }
            mapping_vec.push_back(tmp);
        }
        string sub_str=digits.substr(1,digits.length()-1);
        vector<string> mid_vec=mapping_vec[atoi(digits.substr(0,1).c_str())];
        vector<string> pre_res=letterCombinations2(sub_str);
        vector<string> cur_res;
        for(int i=0;i<mid_vec.size();i++){
            for(int j=0;j<pre_res.size();j++){
                string cur_string=mid_vec[i]+pre_res[j];
                cur_res.push_back(cur_string);
            }
        }
        return cur_res;
    }

update: 2015-01-22 使用DFS + map初始化

//DFS 2ms
class Solution {
private:
    std::map<string, string> map1;
public:
    Solution () {
        map1["2"] = "abc";
        map1["3"] = "def";
        map1["4"] = "ghi";
        map1["5"] = "jkl";
        map1["6"] = "mno";
        map1["7"] = "pqrs";
        map1["8"] = "tuv";
        map1["9"] = "wxyz";
    }
    void letterCombinations(string digits, int k, string current, vector<string>& res) {
        if (k == digits.length()) {
            res.push_back(current);
        } else {
            for (int i = 0; i < map1[digits.substr(k, 1)].length(); ++i) {
                current += map1[digits.substr(k,1)].substr(i,1);
                letterCombinations(digits, k+1, current, res);
                current = current.substr(0, current.length() - 1);
            }
        }
    }
    vector<string> letterCombinations(string digits) {
        vector<string> result;
        letterCombinations(digits, 0, "", result);
        return result;
    }
};


update: 2015-03-08 使用DFS + string array初始化

//2ms 
class Solution {
private:
    string* int2string;  // private类型的变量,数组指针。
public:
    Solution(){ // 构造函数是public,里面进行string int2string的初始化。
        int2string = new string [10];
        int2string[0] = "";
        int2string[1] = "";
        int2string[2] = "abc";
        int2string[3] = "def";
        int2string[4] = "ghi";
        int2string[5] = "jkl";
        int2string[6] = "mno";
        int2string[7] = "pqrs";
        int2string[8] = "tuv";
        int2string[9] = "wxyz";
    }
    void dfs(string &digits, int start, int end, string& current, vector<string>& final_vector) {
        if (start == end) {
            final_vector.push_back(current);
        } else {
            int index = digits[start] - '0';
            for (int i = 0; i < int2string[index].length(); ++i) {
                current = current + int2string[index].substr(i,1);
                dfs(digits, start + 1, end, current, final_vector);
                current = current.substr(0, current.length() -1);
            }
        }
    }
    vector<string> letterCombinations(string digits) {
        vector<string> final_vector;
        if (digits == "") return final_vector;
        string current = "";
        dfs(digits, 0, digits.length(), current, final_vector);
        return final_vector;
    }
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值