LeetCode OJ-14.Longest Common Prefix

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);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值