给定一个数字字符串,求所有可能的点分十进制ip。
显然是dfs,有一些小细节写在了注释里。0ms。
#include <stdlib.h>
#include <string.h>
/* @param: char* s 剩下的字符串
char* pre 未完成的转换字符串,未完成时总是以.结尾
char** result 指针数组,需要free释放内存
char* returnSize 指针数组的长度
int dep 调用深度,范围由4到1 */
static void dfs(char* s, char* pre, char** result, int* returnSize, int dep) {
// 接下来需要解析的字符串的长度,应该在[dep, dep*3]的范围内
if (strlen(s) < dep || strlen(s) > dep * 3)
return;
// 成功转换,压入result指针数组
if (s[0] == 0) {
int len = strlen(pre);
pre[--len] = 0; // 去掉pre结尾的.
result[*returnSize] = malloc(len + 1);
strcpy(result[*returnSize], pre);
(*returnSize)++;
return;
}
int i, j;
char tmp[4];
// 依次枚举接下来要转换的数字长度
for (i = 1 ; i <= 3 ; i++) {
for (j = 0 ; j < i ; j++)
tmp[j] = s[j];
tmp[j] = 0;
int num = atoi(tmp);
if (i == 1 || (i == 2 && num > 9) || (i == 3 && num > 99 && num < 256)) {
int oldpre = strlen(pre);
strcat(pre, tmp);
strcat(pre, ".");
dfs(s+i, pre, result, returnSize, dep-1);
pre[oldpre] = 0; // backtrace
}
}
}
char** restoreIpAddresses(char* s, int* returnSize) {
char** result = malloc(sizeof(char*) * 100); // 100个比较保险,在leetcode测试中需要20个即可
char* pre = malloc(20);
pre[0] = 0;
*returnSize = 0;
dfs(s, pre, result, returnSize, 4);
free(pre);
return result;
}
ps小感悟:果然C语言0ms完全领先,看discuss里 C++ 4ms极限,以及 java 200ms+也是笑了。果然C的效率高,用起来有成就感。
不过用C确实挺麻烦的。。。对比discuss里的C++代码,明显C++代码的可读性更好,我的程序中还是有一些逻辑无关的代码。