题目
1、题目描述
国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如:
‘a’ 对应 “.-” ,
‘b’ 对应 “-…” ,
‘c’ 对应 “-.-.” ,以此类推。
为了方便,所有 26 个英文字母的摩尔斯密码表如下:
[“.-”,“-…”,“-.-.”,“-…”,“.”,“…-.”,“–.”,“…”,“…”,“.—”,“-.-”,“.-…”,“–”,“-.”,“—”,“.–.”,“–.-”,“.-.”,“…”,“-”,“…-”,“…-”,“.–”,“-…-”,“-.–”,“–…”]
给你一个字符串数组 words ,每个单词可以写成每个字母对应摩尔斯密码的组合。
例如,“cab” 可以写成 “-.-…–…” ,(即 “-.-.” + “.-” + “-…” 字符串的结合)。我们将这样一个连接过程称作 单词翻译 。
对 words 中所有单词进行单词翻译,返回不同 单词翻译 的数量。
2、原题链接
解题报告
1、解题思路
(
1
)
(1)
(1) 方法一:把每个字符串编码然后存入哈希表中,返回哈希表长度。
(
2
)
(2)
(2) 方法二:由莫斯编码的特性可知,每个字母对应于一个由一系列点和短线组成。所以整个字符串只有两种字符。不妨试试字典树。
(
2.1
)
(2.1)
(2.1) 符号 '-'
和'.'
对应的ASCII
码为
45
45
45
46
46
46 所以他的后续节点只需要一个包含有两个指针的指针数组即可,索引的时候用当前字符idx = str[k] - '-'
所得到的值做下标索引。
(
2.2
)
(2.2)
(2.2) 将所有字符串加入字典树。
(
2.3
)
(2.3)
(2.3) 遍历字典树统计所有节点end
值为true的个数。
2、解题方法
字典树;DFS;
2、代码详解
1)字典树结构定义
typedef struct node{
bool end;
struct node*next[2];
}NODE;
2)字典树初始化
char *trans[] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
int i, j, k, idx;
NODE *root = (NODE*)calloc(1, sizeof(NODE));
NODE *p;
for(i = 0; i < wordsSize; ++i){
p = root;
for(j = 0; words[i][j]; ++j){
char *str = trans[words[i][j] - 'a'];
for(k = 0; str[k]; ++k){
idx = str[k] - '-';
if(p->next[idx]){
p = p->next[idx];
continue;
}
p->next[idx] = (NODE*)calloc(1, sizeof(NODE)); //左- 右.
p = p->next[idx];
}
}
p->end = true;
}
return root;
3)DFS搜索
后序遍历统计end;
void dfs(NODE *root, int *ans){
if(root){
dfs(root->next[0], ans);
dfs(root->next[1], ans);
if(root->end){
++(*ans);
}
free(root);
}
}
4)主函数
int uniqueMorseRepresentations(char ** words, int wordsSize){
int ans;
ans = 0;
dfs(init(words, wordsSize), &ans);
return ans;
}
总结
字典树不会重复存,多个相同字符串在字典树中只有一种情况!