LeetCode14-最长公共前缀
14. 最长公共前缀:
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
提示:
- 1 <= strs.length <= 200
- 0 <= strs[i].length <= 200
- strs[i] 仅由小写英文字母组成
解题思路1:
一来就想到了字典树,以第一个字符串为目标搜搜索每个节点是否包含所有字符串
static const int MAXN=50000;
struct DicTree{
int cnt[MAXN];
int tree[MAXN][26];
int tot;
void init()
{
tot=0;
memset(cnt,0,sizeof(cnt));
memset(tree,0,sizeof(tree));
}
void Insert(string s)
{
int len=s.size();
int now=0;
for(int i=0;i<len;i++)
{
int id=s[i]-'a';
if(!tree[now][id])
tree[now][id]=++tot;
now=tree[now][id];
cnt[now]++;
}
}
int search(string s)
{
int len=s.size();
int now=0;
for(int i=0;i<len;i++)
{
int id=s[i]-'a';
if(!tree[now][id])
return 0;
now=tree[now][id];
}
return cnt[now];
}
string getAns(string s,int num)
{
cout<<s<<" ,num="<<num<<endl;
string ans=""; //因为是所有公共前缀,所有随便用一个string就行,这里用strs[0];
int len=s.size();
int now=0;
for(int i=0;i<len;i++)
{
int id=s[i]-'a';
now=tree[now][id];
if(cnt[now]!=num) //不包含所有字符串strs
break;
ans+=s[i];
}
return ans;
}
}dicTree;
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
dicTree.init();
int len=strs.size();
for(int i=0;i<len;i++)
dicTree.Insert(strs[i]);
return dicTree.getAns(strs[0],len);
}
};
解题思路2:
二分第一个字符串,判断是否所有的字符串都包含0到mid这个前缀,这里是找到第一个不符合条件的位置,对于数来说就是第一个大于的位置,就是upper_bound
class Solution {
public:
bool is_match(const vector<string>str,int len)
{
int str_len=str.size();
int x=str[0].size();
if(len==x)
len--;
for(int i=1;i<str_len;i++)
{
int num=str[i].size();
if(num<len)
return false;
for(int j=0;j<=len;j++)
if(str[i][j]!=str[0][j])
return false;
}
return true;
}
string longestCommonPrefix(vector<string>& strs) {
int len=strs[0].size();
int l=0,r=len,mid;
while(l<r)
{
mid=(l+r)>>1;
bool flag=is_match(strs,mid);
if(flag)
l=mid+1;
else
r=mid;
//printf("1:l=%d,r=%d\n",l,r);
}
//printf("l=%d,r=%d\n",l,r);
return strs[0].substr(0,l);
}
};