[LeetCode] 电话号码的字母组合


题目

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
(题目链接 https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)

问题分析

刚拿到这道题的时候没什么思路,只能顺着逻辑想。每个数字对应着三个或者四个字母,也就是说每个位置我们会有三个或者四个选择。那么似乎我们可以用递归来解决问题,因为每个位置的字母我们都需要做多种选择,而做出这种选择后下一个位置同样也需要这么做。那么我们先依据这个思路写一个递归函数

/*
    C++代码
*/

/*
    ret      为储存最终结果的数组
    map   是字母到数字的映射表
    digits  是一串要转换数字
    s         由数字转换成的字符串
*/
void fun(vector<string>& ret, const char map[8][5], const string& digits, string& s) {
	if (s.length() < digits.length()) {
		for (int i = 0; i < strlen(map[(digits[s.length()] - '0') - 2]); i++) {
			s.push_back(map[(digits[s.length()] - '0') - 2][i]);
			fun(ret,map,digits,s);
			s.pop_back();
		}
	}
	else if (s.length() == digits.length()) {
		ret.push_back(s);
	}
}

可能有朋友发现这就是一个深度优先搜索的过程,那么恭喜,后面的内容将十分容易理解,如果没有反应过来,后面还有图片助于理解。
这个函数的部分执行过程见下图(其实是画图太麻烦懒得画全过程,也没必要),看了之后理解起来应该更容易。

由于最终我们要返回一个数组给LeetCode,外层套上一个函数

/*
    C++代码
*/
vector<string> letterCombinations(string digits) {
        vector<string> ret;
	    if (digits.length() == 0) {
		    return ret;
	    }
	    char map[8][5] = {
	    	{'a','b','c',0},
	    	{'d','e','f',0},
	    	{'g','h','i',0},
	    	{'j','k','l',0},
	    	{'m','n','o',0},
	    	{'p','q','r','s',0},
	    	{'t','u','v',0},
	    	{'w','x','y','z',0}
	    };
	    string s;
	    fun(ret, map, digits, s);
	    return ret;
    }

时间复杂度O(4^n) ,空间复杂度O(n)。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM