Categories
不学无术

LeetCode 17. Letter Combinations of a Phone Number

原题:https://leetcode.com/problems/letter-combinations-of-a-phone-number/
思路:
就是排列组合全部输出嘛!如果用递归做的话,函数进栈出栈估计会挺费事儿的,所以想个循环呗。假设我们要输出的是一个矩阵形式的东西,第i行j列是第i个答案的第j个字幕,那么主要问题是求出这个字母是啥。
拿原题中给的例子看,对应第一列的输出是a,a,a,b,b,b,c,c,c;第二列是d,e,f,d,e,f,d,e,f. 可以比较容易知道,第一列的字母是每3列变换一次,第二列则是每1列变换一次。即,假设最终由N个可能结果(N行),每一列代表按了一个数字键,其对应字母有m[j]个那么:

  1. 第1列(j=0)字母是每Y[0] = N/m[j]改变一次的;
  2. 第2列(j=1)字母是每Y[1]/m[j]改变一次的;
  3. 以此类推…

所以第i行第j列的字符应该是chr[ dight[i] ] [ (j/Y[j])%当前数字对应可能结果的个数 ]
其中j/Y[j]是当前跳到了哪一个“轮回”了,比如例子里面j=4,Y[0]=9/3=3,那么就应该跑到第二个字母”b”了。
代码:

struct ChrNode{
    int size;
    ChrNode() {}
};
const char chrs[][4] = { {' '}, {'X'}, {'a','b','c'}, {'d','e','f'},
                         {'g','h','i'}, {'j','k','l'}, {'m','n','o'},
                         {'p','q','r','s'}, {'t','u','v'}, {'w','x','y','z'}};
class Solution {
public:
    int childSize(char c) {
        switch (c) {
            case '2': case '3': case '4': case '5': case '6': case '8': return 3;
            case '7': case '9': return 4;
        }
        return 1;
    }
    void makeNode(ChrNode* node, char d) {
        node->size = childSize(d);
    }
    vector<string> letterCombinations(string digits) {
        vector<ChrNode> nodes;
        //Build tree
        int digiSize = digits.size();
        int solutionSz = 1;
        for(int i=0; i<digiSize; i++){
            ChrNode node;
            makeNode(&node, digits[i]);
            nodes.push_back(node);
            solutionSz *= childSize(digits[i]);
        }
        vector<string> solutions;
        if(solutionSz <= 1)
            return solutions;
        for(int row=0; row<solutionSz; row++)
            solutions.push_back("");
        char c;
        int jmp = solutionSz;
        for(int i=0; i<digiSize; i++) {
            jmp /= nodes[i].size;
            int jmp_diff;
            for(int j=0; j<solutionSz; j++) {
                jmp_diff = j / jmp;
                c = chrs[digits[i] - '0'][jmp_diff % nodes[i].size];
                solutions[j] += c;
            }
        }
        return solutions;
    }
};

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.