寻找若干个字符串的最长公共前缀 Longest Common Prefix

来源:互联网 发布:机柜网络模块接线图 编辑:程序博客网 时间:2024/05/01 09:13

问题:给出若干个字符串,找出他们的最长公共前缀子串。问题源于Leetcode。

假设这里字符串有n个,平均长度为m。

方法:

1、所求的最长公共前缀子串一定是每个字符串的前缀子串。所以随便选择一个字符串作为标准,把它的前缀串,与其他所有字符串进行判断,看是否是它们所有人的前缀子串。这里的时间性能是O(m*n*m)。

2、列出所有的字符串的前缀子串,将它们合并后排序,找出其中个数为n且最长的子串。时间性能为O(n*m+m*n*log(m*n))

3、纵向扫描:从下标0开始,判断每一个字符串的下标0,判断是否全部相同。直到遇到不全部相同的下标。时间性能为O(n*m)。

4、横向扫描:前两个字符串找公共子串,将其结果和第三个字符串找公共子串……直到最后一个串。时间性能为O(n*m)。

5、借助trie字典树。将这些字符串存储到trie树中。那么trie树的第一个分叉口之前的单分支树的就是所求。


代码一(方法1)

class Solution {public:    string longestCommonPrefix(vector<string> &strs) {        // Note: The Solution object is instantiated only once and is reused by each test case.        if(strs.size() == 0)            return "";        if (strs.size() ==1)            return strs[0];        string s = strs[0];        vector<string> spre;        int i;        for(i=1;i<=s.length();i++)            spre.push_back(s.substr(0, i));        string longest = "";        int flag;        for(int j=0; j<spre.size();j++)        {            flag = 1;            for(i=1;i<strs.size();i++)            {                if(!isPrefix(strs[i], spre[j]))                    flag = 0;            }            if(flag == 0)                break;            longest = spre[j];        }return longest;    }    bool isPrefix(string m, string p)    {        int n = 0;        if(m.length() < p.length())            return false;        while(n<p.length())        {            if(m[n] == p[n])                n++;            else                return false;        }        return true;    }};

代码二(方法3):纵向扫描。

class Solution {public:    string longestCommonPrefix(vector<string> &strs) {        if(strs.empty())            return "";        int num = strs.size();        int len = strs[0].size();        for(int i=0;i<len;i++)            for(int j=1;j<num;j++)            {                if(i > strs[j].size() || strs[j][i] != strs[0][i])                    return strs[0].substr(0, i);            }        return strs[0];    }};
代码三(方法5):字典树。

class Solution {public:typedef struct node { char ch;int branch ; //记录分支树,方便最后查询int times;node* child[26];}node, *Trie;Trie init_Trie(){Trie root = (node*)malloc(sizeof(node)); //Trie树的根节点不存储数据root->branch = 0;root->times = 0;for(int i=0;i<26;i++)root->child[i] = NULL;return root;}void insert_Trie(Trie root, const string str){int n = str.length();if(n == 0){root->times ++;return;}int i=0;int idx;node *p = root;root->times++;while(i<n){idx = str[i] - 'a';if(p->child[idx] != NULL){p = p->child[idx];p->times ++;i++;}else{node* tmp = (node*)malloc(sizeof(node));tmp->ch = str[i];tmp->branch = 0;tmp->times = 1;for(int j=0;j<26;j++)tmp->child[j] = NULL;p->branch ++;p->child[idx] = tmp;p = tmp;i++;}}}string longestCommonPrefix(vector<string> &strs){int n = strs.size();if(n == 0)return "";int i;Trie root = init_Trie();for(i=0;i<n;i++)insert_Trie(root, strs[i]);i = 0;node* p = root;while(i<strs[0].length() && p->branch == 1 && p->times == n){p = p->child[strs[0][i] - 'a'];i++;}if(p->times < n)i--;return strs[0].substr(0,i);}    };

原创粉丝点击