leecode 解题总结:17. Letter Combinations of a Phone Number

来源:互联网 发布:linux程序设计pdf下载 编辑:程序博客网 时间:2024/05/01 15:06
#include <iostream>#include <stdio.h>#include <string>#include <vector>#include <map>#include <sstream>using namespace std;/*问题: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.分析:1:无对应字母2: abc3: def4: ghi5: jkl6: mn07: pqrs8: tuv9: wxyz也就是说:实际上就是把 数字--->字母,多个数字对应字母数组进行笛卡尔积的操作。可以:先建立<数字,字母数组>的映射,然后找到获取所有数字各自对应的字母数组如果数字很长,会导致设定的嵌套循环很长。这个应该是递归来生成字符串,可以先生成一个完整的字符串。比如我输入的是数字:237,对应第一个字符串(每个自数字对应字符串取第一个数字为)adp,那么接下来优先变换最后面,p变成q,得到adq,q变成r变成adr,然后ads当变换到s(数字7对应最后一个字母的时候),此时设置应该变换的是中间数字3对应第一个字母为e,同时设置将s变为p,此时得到aep,....也就是说:每当遍历到第i个数字对应的最后一个字母时,此时设定第i-1个数字对应的字母进行变换,同时将第i个数字对应的字母变成起始字母;重复上述过程,直到每个字母都是对应数字中最后一个字母注意:1 4个字母的2 数字1没有数字输入:1122378输出:空字符串a, b, cad, ae, af, bd, be, bf, cd, ce, cfpt, pu, pv, qt, qu, qv, rt, ru, rv, st, su, sv关键:1 比如我输入的是数字:237,对应第一个字符串(每个自数字对应字符串取第一个数字为)adp,那么接下来优先变换最后面,p变成q,得到adq,q变成r变成adr,然后ads当变换到s(数字7对应最后一个字母的时候),此时设置应该变换的是中间数字3对应第一个字母为e,同时设置将s变为p,此时得到aep,....也就是说:每当遍历到第i个数字对应的最后一个字母时,此时设定第i-1个数字对应的字母进行变换,同时将第i个数字对应的字母变成起始字母;重复上述过程,直到每个字母都是对应数字中最后一个字母2while(!isFinish(firstLetter , finishStr)){i = letterSize - 1;ch = firstLetter.at(i);nextCh = getNextChar(firstLetter , i , letters);firstLetter.at(i) = nextCh;int j = i;//如果当前字符已经变成首个字符,说明在第i位上已经完整遍历过一遍,此时第i-1位的字符需要变成当前字符后面一位while( j >= 1 && nextCh == letters.at(j).at(0) ){j--;nextCh = getNextChar(firstLetter ,j , letters );firstLetter.at(j) = nextCh;//results.push_back(firstLetter);//这里还不是最终的值,需要从循环出来才是}results.push_back(firstLetter);}*/class Solution {public://获取字符串firstLetter中下标为index对应的字符的下一个字符char getNextChar(string& firstLetter , int index , vector<string>& letters){if(firstLetter.empty() || letters.empty() || index < 0){return '#';}int stringSize = firstLetter.size();int letterSize = letters.size();if(stringSize != letterSize){return '#';}if(index >= letterSize ){return '#';}char ch = firstLetter.at(index);string str = letters.at(index);int len = str.length();//如果字符串中已经到达最后一个字符for(int i = 0 ; i < len ; i++ ){if( str.at(i) != ch ){continue;}//如果找到该字符,获取下一个字符else{//如果字符在末尾,需要返回首个字符if(len - 1 == i){return str.at(0);}else{return str.at(i+1);}}}return '#';}//获取当前数字对应的最后一个组合的字符串:从每个数字对应的字符串中获取最后一个字符组成的字符串即可string getFinishString(vector<string>& letters){if(letters.empty()){return "";}int size = letters.size();string str;int len;stringstream stream;for(int i = 0 ; i < size ; i++){str = letters.at(i);if(str.empty()){continue;}len = str.length();stream << str.at(len -1);}return stream.str();}//如果当前字符串,等于最终的递归组合字符串,就输出bool isFinish(string& firstLetter, string& finishString){if(firstLetter == finishString){return true;}else{return false;}}vector<string> getLetterCombinations(string firstLetter , vector<string>& letters){vector<string> results;if(firstLetter.empty() || letters.empty()){return results;}int stringSize = firstLetter.size();int letterSize = letters.size();if(stringSize != letterSize){return results;}//逆序遍历每一个字符,获取下一个字符串char ch;char nextCh;results.push_back(firstLetter);string finishStr = getFinishString(letters);int i;while(!isFinish(firstLetter , finishStr)){i = letterSize - 1;ch = firstLetter.at(i);nextCh = getNextChar(firstLetter , i , letters);firstLetter.at(i) = nextCh;int j = i;//如果当前字符已经变成首个字符,说明在第i位上已经完整遍历过一遍,此时第i-1位的字符需要变成当前字符后面一位while( j >= 1 && nextCh == letters.at(j).at(0) ){j--;nextCh = getNextChar(firstLetter ,j , letters );firstLetter.at(j) = nextCh;//results.push_back(firstLetter);//这里还不是最终的值,需要从循环出来才是}results.push_back(firstLetter);}return results;}    vector<string> letterCombinations(string digits) {vector<string> results;//如果数字为空,直接返回空if(digits.empty()){return results;}        //先建立数字到字母的映射map<char , string> digitToLetter;digitToLetter['1'] = "";digitToLetter['2'] = "abc";digitToLetter['3'] = "def";digitToLetter['4'] = "ghi";digitToLetter['5'] = "jkl";digitToLetter['6'] = "mno";digitToLetter['7'] = "pqrs";digitToLetter['8'] = "tuv";digitToLetter['9'] = "wxyz";//接下来,对每个数字分别提取出其对应数组int length = digits.length();char digit;vector<string> letters;string letter;string firstLetter = "";stringstream stream;for(int i = 0 ; i < length ; i++){digit = digits.at(i);//如果字母不在0~9中,直接continue;注意由于1对应无字字母,直接过滤if(digit <= '1' || digit > '9'){continue;}//获取letter = digitToLetter[digit];letters.push_back(letter);stream << letter.at(0);}firstLetter = stream.str();results = getLetterCombinations(firstLetter , letters);return results;    }};void print(vector<string>& strings){if(strings.empty()){cout << "no result" << endl;return;}int size =  strings.size();for(int i = 0 ; i < size ; i++){cout << strings.at(i) << " ";}cout << endl;}void process(){string num;vector<string> strings;while(cin >> num){Solution solution;strings = solution.letterCombinations(num);print(strings);}}int main(int argc , char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击