LeetCode:17.电话号码的字母组合

题目

LeetCode:Letter Combinations of a Phone Number

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

输入: "23"
输出: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

思路

写此题时,对c++并不了解,因此用的c写,花费了好些时间。
首先开辟足够的空间,这个不难计算,因此注释也就不多赘述,关键是下面的字符串操作。
核心是分部分处理,例如1对应abc,就将所有字符串分成三个部分,比如一共27个字符串排列的话,前9个则全部a开头,中间9个全b开头,后面9个全部c开头。
紧接着比如第二个数字是3,对应ghi,则将第一次分的三部分取出一部分也就是9个字符串,分成三部分,前3个字符串全部加g,中间三个全部加h,后面三个全部加i,其他18个字符串也如此处理。
……
电话全排列

代码

查看更多LeetCode代码

/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
char** letterCombinations(char* digits, int* returnSize) {
	//正常求法是递归求解,但是c写起来真的是太不方便了,不能像c++那样string + string
	//而且一般递归问题改成非递归都很麻烦,不过经历了一下午还是解决了
	char* cur = digits;
	int cur_divide = 0;//当前划分区间
	int prev_divide = 0;//前一次划分区间
	char** ret = NULL;
	const char ch[10][5] = { "","","abc","def","ghi","jkl","mno","pqrs","tuv", "wxyz" };
	int str_legth = strlen(digits) + 1;//包含'\0',所以+1
	int i = 0;
	*returnSize = 1;
	while (*cur != '\0')
	{
		if (*cur != '7' && *cur != '9')
		{
			(*returnSize) *= 3;
		}
		else
		{
			(*returnSize) *= 4;
		}
		cur++;
	}
	cur = digits;
	cur_divide = (*returnSize);
	ret = (char**)malloc(sizeof(char*) * (*returnSize));
	for (int i = 0; i < (*returnSize); i++)
	{
		*(ret + i) = (char*)malloc(sizeof(char) * str_legth);
	}
	if (str_legth == 1)
	{
		*returnSize = 0;
		return ret;
	}
	while (*cur != '\0')
	{
		int start = 0;
		int ret_start = 0;
		int ch_index = 0;//字符的位置下标
		//这里的str_legth和前面的意义不同,前面表示给的digits的长度,这里当做数字对应的字符串长度
		//比如2对应就是3——"abc",7对应4——"pqrs"
		str_legth = strlen(ch[*cur - '0']);
		prev_divide = cur_divide;
		cur_divide /= str_legth;
		//区间划分很重要,当数字对应的字符是3个,就在前一个基础上分为3个区,4个即在前一个基础上划分四个区间
		while (start < prev_divide)
		{
			ret_start = start;//这里比较难懂,之后会写博客来配图解释
			while (ret_start < (*returnSize))
			{
				//由于区间是分散的,所以每次开始的位置都不一样
				for (i = ret_start; i < ret_start + cur_divide; i++)
				{
					*(*(ret + i) + (cur - digits)) = ch[*cur - '0'][ch_index];//在对应位置放入字符
				}
				ret_start += prev_divide;
			}
			ch_index++;
			start += cur_divide;
		}
		cur++;
	}
	//最后在字符串尾部加'\0'
	for (i = 0; i < (*returnSize); i++)
	{
		*(*(ret + i) + (cur - digits)) = '\0';
	}
	return ret;
}
发布了89 篇原创文章 · 获赞 96 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Boring_Wednesday/article/details/83033600