- 字典序、快排
一種很巧妙的做法,雖然時間複雜度有點高。
通過排序,只要比較一前一後兩個字符串即可,這個兩個字符串有的前綴,那麼中間的所有字符串也都有這樣的前綴。
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0){
return "";
}
if(strs.size()==1){
return strs[0];
}
sort(strs.begin(),strs.end());
string &s1 = strs[0];
string &s2 =strs[strs.size()-1];
int i;
for(i=0;i<min(s1.size(),s2.size());i++){
if(s1[i]!=s2[i]){
break;
}
}
return s1.substr(0,i);
}
};
- 暴力
別人的,很簡潔,
時間複雜度。
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
string res = strs.empty() ? "" : strs[0];
for (string s : strs)
while (s.find(res) != 0) res = res.substr(0, res.length() - 1);
return res;
}
};
最簡單的暴力法。
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0){
return "";
}
int len = INT_MAX;
for(string &s:strs){
len = min(len,(int)s.size());
}
string res = strs[0];
int i;
for(i=1;i<=len;i++){
for(string &s:strs){
if(s.find(res.substr(0,i))!=0){
return res.substr(0,i-1);
}
}
}
return res.substr(0,len);
}
};
- 前綴樹
看到字符串的公共前綴,我就想到了前綴樹,雖然此題並不需要。
思路,每次插入字符串到字典樹裏面,tot
變量加1,這個字符串對應的每個節點值也加1。
最後,遍歷這棵樹,求出使得某個深度之前的所有節點的值都是tot
,那麼這個深度就是最長前綴的長度。
用深搜來實現。
class Trie{
struct Node{
int cnt = 0;
Node* childs[26] = {0};
};
Node *root;
int tot = 0,depth = 0;
public:
Trie(){
root = new Node;
}
void insert(string s){
tot++;
Node *p = root;
p->cnt++;
for(char c:s){
if(p->childs[c-'a'] ==nullptr){
p->childs[c-'a'] = new Node;
}
p = p->childs[c-'a'];
p->cnt++;
}
}
int askLargestPrefix(){
dfs(root,0);
return depth;
}
void dfs(Node *root,int dpt){
if(!root || root->cnt<tot){
return;
}
depth = max(depth,dpt);
for(int i=0;i<26;i++){
dfs(root->childs[i],dpt+1);
}
}
};
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0){
return "";
}
Trie trie;
for(string &s:strs){
trie.insert(s);
}
int len = trie.askLargestPrefix();
return strs[0].substr(0,len);
}
};