LeetCode OJ-14.Longest Common Prefix
题目描述
Write a function to find the longest common prefix string amongst an array of strings.
Subscribe to see which companies asked this question.
Show Tags
题目理解
简单来说就是求解最长公共前缀,如”abc”,”abcddf”的最长公共前缀就是”abc”。这个题目可以用Trie树来解决,需要注意的点,在代码注释中可以找到。暴力搜索太过耗时,而且也不容易实现。不了解的Trie树可以参见Trie树结构与实现。
Code
typedef struct trie_tree {
int cnt; // 该节点表示的字符出现的次数
struct trie_tree *next[26]; // 记录子节点的指针数组
trie_tree() : cnt(0) {
for (int i = 0; i < 26; ++i) {
next[i] = 0;
}
}
} trie_t;
void trie_init(trie_t **root)
{
*root = new trie_t();
}
void trie_create(const std::string &str, trie_t *root)
{
int i;
int len = (int) str.length();
trie_t *cur = root;
for (i = 0; i < len; ++i) {
if (cur->next[str[i] - 'a'] == 0) {
cur->next[str[i] - 'a'] = new trie_t();
}
cur = cur->next[str[i] - 'a'];
++(cur->cnt);
}
}
std::string trie_search_lcp(trie_t *root, size_t strs_cnt, size_t min_len)
{
std::string res;
trie_t *cur = root;
int i;
int index;
int scnt;
while (cur != 0) {
scnt = 0;
for (i = 0; i < 26; ++i) { // 寻找next路径,以构成最长公共前缀
if (cur->next[i] != 0) {
++scnt;
index = i;
}
}
if (strs_cnt == 0) { // 字符串集合为空,最长公共前缀为空
return res;
}
else if (strs_cnt == 1) { // 字符串集合仅有1个元素,最长公共前缀即为该元素
if (scnt == 1) { // next仅有1个节点
res.push_back('a' + index);
cur = cur->next[index];
}
else { // next无节点
cur = 0;
}
}
else { // 字符串集合有多于1个元素
if (scnt == 1) { // next仅有1个节点
// 节点字符出现次数与集合元素数量相等
if (cur->next[index]->cnt == strs_cnt) {
// 最长公共前缀的最大长度一定小于等于字符串集合中最短的字符串
if (res.length() < min_len) {
res.push_back('a' + index);
}
}
cur = cur->next[index];
}
else { // 搜索到next不止有1个节点
cur = 0;
}
}
}
return res;
}
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
trie_t *root;
std::vector<std::string>::iterator iter;
trie_init(&root);
size_t min_len = INT_MAX; // 记录vector中所有字符串的最小长度
for (iter = strs.begin(); iter != strs.end(); ++iter) {
min_len = min_len < (*iter).length() ? min_len : (*iter).length();
trie_create(*iter, root);
}
//std::cout << root->next['c' - 'a']->cnt << std::endl;
return trie_search_lcp(root, strs.size(), min_len);
}
};