题目如下,输入一串数字,根据电话键盘布局输出此数字可能代表的字母组合。
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; } };