回溯算法是对树形或者图形结构执行一次深度优先遍历,实际上类似枚举的搜索尝试过程,在遍历的过程中寻找问题的解。
深度优先遍历有个特点:当发现已不满足求解条件时,就返回,尝试别的路径。此时对象类型变量就需要重置成为和之前一样,称为「状态重置」。
许多复杂的,规模较大的问题都可以使用回溯法,有「通用解题方法」的美称。实际上,回溯算法就是暴力搜索算法,它是早期的人工智能里使用的算法,借助计算机强大的计算能力帮助我们找到问题的解。
给定一个仅包含数字 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);
}
}