首先是用C语言写,因为平时我开发需要熟悉C。其次会详细解释一下这道题算法的知识点,但是是动态规划。这道题还有另一种更低时间复杂度的,这里不讲。
n
,当前子问题字符串长i
,比上一次增加了1个字符,我只用确定这个字符对以前状态的影响就好了。int minExtraChar(char * s, char ** dictionary, int dictionarySize) {
int length = strlen(s)+1; // 要匹配的字符串长度,不会包含'\0'的, +1是因为初始状态要写0
int dp[length]; // 保存子问题的状态信息
int i;
//把字典放入哈希表用于查找
for (i = 0; i < dictionarySize; i++){
add(dictionary[i]);
}
dp[0] = 0; // 初始化字符串长度为0
for (int i = 1; i < length; i++) { // 枚举子问题
//如果整个状态没有变化
dp[i] = dp[i - 1] + 1;
//罗列可能造成状态变化的原因,即与字典中的每个字符串做后缀匹配
for (int j = i - 1; j >= 0; j--) {
if (find(substr(s, j, i-j))!=NULL) {
dp[i] = min(dp[i], dp[j]);
}
}
}
hashFree();
return dp[length-1];
}
C的哈希表在#include “uthash.h”,但是OJ要自己写。
typedef struct {
char* key;
UT_hash_handle hh;
} Hash;
Hash *myHash = NULL;
int min(int a, int b) {
return a > b ? b : a;
}
char *substr(char *str, int start, int len) {
char *sub = (char*) malloc(len + 1);
strncpy(sub, str + start, len);
sub[len] = '\0';
return sub;
}
Hash* find(char* key)
{
Hash *s = NULL;
HASH_FIND_STR(myHash, key, s);
return s;
}
void add(char* key){
Hash *s = find(key);
if(s == NULL){
s = (Hash *)malloc(sizeof(Hash));
s->key = key;
HASH_ADD_STR(myHash, key, s);
}
}
void hashFree() {
Hash *curr = NULL, *tmp = NULL;
HASH_ITER(hh, myHash, curr, tmp) {
HASH_DEL(myHash, curr);
free(curr);
}
}