问题描述:
给k个字符串,求出他们的最长公共前缀(LCP)
解题思路:
自定义一个字典树结构,每个树节点有一个int型整数count,表示有多少个字符串经过该节点。除此之外,每个节点还有58个指针指向下一层节点,设计成58个指针,是因为‘a’与‘A’的ASCII编码相差58。
我们使用字典树表示所有字符串,构造字典树的时间复杂度为O(n*length),其中n为字符串个数,length为字符串的平均长度。
最后从根节点出发,遍历它的节点指针,然后比较它的下一个节点的成员变量count是否等于k,若不相等,说明它还有其他分支,则最长公共前缀到此为止。查找过程的时间复杂度为O(length),则总的时间复杂度为O(n*length)。
实现代码:
class Solution {
public:
/**
* @param strs: A list of strings
* @return: The longest common prefix
*/
class trie{
public:
trie(){
count = 1;
for(int i=0;i<58;i++)
next[i] = NULL;
};
int count;
trie* next[58];
};
string longestCommonPrefix(vector<string> &strs) {
// write your code here
string res;
if(strs.size()==0)
return res;
trie* head = new trie();
for(int i=0;i<strs.size();i++){
trie* pre = head;
for(int j=0;j<strs[i].size();j++){
if(pre->next[strs[i][j]-'A']==NULL){
trie* tmp = new trie();
pre->next[strs[i][j]-'A'] = tmp;
} else {
pre->next[strs[i][j]-'A']->count += 1;
}
pre = pre->next[strs[i][j]-'A'];
}
}
while(head){
int i=0;
while(i<58 && head->next[i]==NULL)
i++;
if(i>=58 || head->next[i]->count!=strs.size())
return res;
res += 'A' +i;
head = head->next[i];
}
}
};