leetcode 17 电话号码的字母组合 回溯

回溯算法是对树形或者图形结构执行一次深度优先遍历,实际上类似枚举的搜索尝试过程,在遍历的过程中寻找问题的解。

深度优先遍历有个特点:当发现已不满足求解条件时,就返回,尝试别的路径。此时对象类型变量就需要重置成为和之前一样,称为「状态重置」。

许多复杂的,规模较大的问题都可以使用回溯法,有「通用解题方法」的美称。实际上,回溯算法就是暴力搜索算法,它是早期的人工智能里使用的算法,借助计算机强大的计算能力帮助我们找到问题的解。

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

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

答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。

注意0和1不对应任何字母。

例:输入23,则输出ad,ae,af,bd,be,bf,cd,ce,cf

全文以输入5678为例

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char path[100];
char digits[10];	//键盘输入的数字(5678)
//char result[10];	//每一层循环得到的一个字母组成的输出值(gmpt等)
int len[5];			//存放letters里每个字母组的长度(jkl长3,pqrs对应4)
char *letterMap[10] = {"",     //0
                       "",     //1
                       "abc",  //2
                       "def",  //3
                       "ghi",  //4
                       "jkl",  //5
                       "mno",  //6
                       "pqrs", //7
                       "tuv",  //8
                       "wxyz", //9
};

int top=0;
void dfs(char *digits, int index) {
    //index=digits时,每个字幕组都循环了,退出取值当前下标等于digits数组长度
    if (index == strlen(digits)) {
        for (int i = 0; i < index; ++i) {
            printf("%c",path[i]);
        }
        printf("\n");
        return;
//        printf("%s\n", path);
    }
    int n = digits[index] - '0';
    char * letters = letterMap[n];	//letterMap里数字对应的字母组(例:5对应jkl)
    for (int j = 0; j < strlen(letters); j++) {
        path[top++] = letters[j];	//取第index数字对应的字母组(第2个数字6对应mno)
//        result[index] = ltr[j];
        dfs(digits, index + 1);
        top--;
    }
}
int main() {
    printf("input 2-9:(<10000)");
    scanf("%s", digits);
    dfs(digits, 0);
    return 0;
}

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char digits[10];	//键盘输入的数字(5678)
char result[10];	//每一层循环得到的一个字母组成的输出值(gmpt等)
char *letters[10];	//letterMap里数字对应的字母组(例:5对应jkl)
int len[5];			//存放letters里每个字母组的长度(jkl长3,pqrs对应4)
int m = 0;				//计数,方便查看循环次数和得到的结果数

void cycle(char *digits, int index);

char *letterMap[10] = {"",     //0
                       "",     //1
                       "abc",  //2
                       "def",  //3
                       "ghi",  //4
                       "jkl",  //5
                       "mno",  //6
                       "pqrs", //7
                       "tuv",  //8
                       "wxyz", //9
                      };

int main() {
	printf("input 2-9:(<10000)");
	scanf("%s", digits);
	for (int i = 0; i < strlen(digits); i++) {
		int n = digits[i] - '0';		//把输入的数中的每一个数字转为整型
		//判断输入的数字中是否输入了1和0
		if (n < 2) {
			printf("the %d number is illegal!\n", i + 1);
			return 1;
		}
		letters[i] = letterMap[n];		//得到每个数字对应的字母组
		len[i] = strlen(letters[i]);		//每个字母组的长度
	}
	cycle(digits, 0);
	return 0;
}

void cycle(char *digits, int index) {
	char *ltr;		//指向字母组
	//index=digits时,每个字幕组都循环了,退出取值
	if (index == strlen(digits)) {
		printf("%s\n", result);
	}
	for (int j = 0; j < len[index]; j++) {
		ltr = letters[index];	//取第index数字对应的字母组(第2个数字6对应mno)
		result[index] = ltr[j];
		cycle(digits, index + 1);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值