回溯法——电话号码的字母组合

力扣17题——电话号码的字母组合
一道经典的用回溯法解决的问题

题目描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

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

在这里插入图片描述

示例 1:

输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
示例 2:

输入:digits = “”
输出:[]
示例 3:

输入:digits = “2”
输出:[“a”,“b”,“c”]

代码

char phoneMap[11][5] = {"\0","\0","abc\0","def\0", "ghi\0", "jkl\0", "mno\0", "pqrs\0", "tuv\0", "wxyz\0"};

char* digits_tmp;
int digits_size;

char** combinations;
int combinations_size;

char* combination;
int combination_size;

void backtrack(int index){
    if(index == digits_size){
        char* tmp = malloc(sizeof(char) * (combination_size+1));
        memcpy(tmp,combination,sizeof(char) * (combination_size + 1));
        combinations[combinations_size++] = tmp;
    }else{
        char digit = digits_tmp[index];
        char* letters = phoneMap[digit - '0'];
        int len = strlen(letters);
        for(int i = 0; i < len; i++){
            combination[combination_size++] = letters[i];
            combination[combination_size] = 0;
            backtrack(index + 1);
            combination[--combination_size]=0;
        }
    }
}
char ** letterCombinations(char * digits, int* returnSize){
    combination_size = combinations_size=0;
    digits_tmp = digits;
    digits_size = strlen(digits);
    if(digits_size == 0){
        *returnSize = 0;
        return combination;
    }
    int num = 1;
    for(int i = 0; i <digits_size; i++) num*=4;
    combinations = malloc(sizeof(char*)*num);
    combination = malloc(sizeof(char) * (digits_size+1));
    backtrack(0);
    *returnSize = combinations_size;
    return combinations;
}

可以看到回溯法对于这种带分支的枚举问题很有效,一般回溯问题还有限制条件,用于剪掉不满足条件的。这个题所有的都是可行解。

回溯法经典框架:

void backtracking(int depth){
	if(size == depth){
		具体的操作,如保存可行解
	}else{
		初始化一些变量
		for(int i = 0; i < numsSize; i++){
			将可行解拓展一步;
			backtracking(depth+1);
			回退一步;
		}
	}
}

还是有难度的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值