Python共有前缀,python查找字符串最长公共前缀
写一个函数在字符串数组中寻找最长的公共前缀。
如果公共前缀不存在,则返回空字符串“”。
示例1:
输入:[花,流,飞行]输出: fl示例2:
Input: [dog , racecar , car] Output: 说明:输入没有public前缀。说明:
所有输入只包含小写字母a-z。
关于这个话题,大致有四种解决方案:
1.横向扫描:比较前两个字符串的公共前缀,将结果与第三个字符串进行比较,得到前三个字符串的公共前缀,直到最后一个字符串与第四个字符串进行比较。时间复杂度为o(n*m),n是字符串的个数,m是字符串的平均长度。
2.垂直扫描:扫描每个字符串的第一个字符。如果都相等,继续扫描每个字符串的第二个字符。如果不相等,则返回先前扫描的子字符串。时间复杂度为o(n*m)
3.前缀树:最长的公共前缀必须是每个字符串的前缀部分列,因此可以将某个字符串与所有其他字符串进行比较,以确定前缀列是否是所有其他字符串的前缀。
4.前缀树)以任意字符串为基准,遍历字符串树中的节点信息。具有第一个分支的节点是应该寻找的分割点,并且它是从根节点到该点的字符串中获得的最长公共前缀。
前缀树
概述
前缀,又称字典树、词搜索树、Trie树,是一种多叉树结构,是hash树的变种,与hash效率共同作用,是一种多叉树结构,用于快速检索。
由于典型的APP应用程序用于对大量字符串进行计数和排序,因此它不仅经常用于字符串,还用于对搜索引擎系统中的文本单词进行计数。它的优点是最大限度地减少了不必要的字符串比较,查询效率高于哈希表。
Trie的中心思想是改变空间的时间。使用字符串的常用前缀来减少查询时间,提高效率。
树也有缺点。它们消耗大量内存。
属性:不同字符串只保存一个前缀。
操作:搜索、插入和删除。
举个例子吧。获得一组单词。将获得以下树:
从上面可以看出几种树的特点:
1)根节点不包含字符,除了根节点之外的所有子节点都包含字符。
2)从根节点到节点的路径上的文本与对应于该节点的字符串相连接。
3)每个节点的所有子节点包含不同的字符。
4)每边对应一个单词。每个节点对应一个前缀。一个节点对应最长的前缀,也就是单词本身。
单词inn和单词int有一个共同的前缀“in”,所以它们共享左分支,即根输入。同样,ate、age和adv与ant共享前缀‘A’,因此它们共享从根节点到节点‘A’的边。
查询非常简单。例如,要查找int,请遵循路径i-in-int。
构建Trie的基本算法也很简单,不只是将Trie插入到每个单词的每个字符中。请在插入前检查前缀是否存在。如果存在,分享一下;如果它不存在,创建相应的节点和边。例如,要插入单词add,有以下步骤。
检查前缀“A ”,我们发现边A已经存在。然后沿着边a到节点a。
检查剩余字符串 dd 的前缀 d ,发现边d已经从节点a开始存在,然后,沿着边d转到节点ad。
检查最后一个单词‘D’,这样从节点ad开始,边D就没了,所以让节点AD的子节点adD,把边AD-add标为D。
特定代码:
//定义前缀树节点的数据结构
结构树节点
{
TrieNode * next[26];
char c;
bool isWord//保存当前字符是否是单词的结尾
trienode(char_c ) :c ) _c),是word (false))。
{
memset(next,0,sizeof)trienode *)26);
() ) ) ) )。
(;
实现树前缀树
类Trie {(
公共:
树*根;
/* * initializeyourdatasstructurehere。* /
特里().
节点(“”);
() ) ) ) )。
/**将单词插入到trie中。*/
在voidinsert(stringword )//前缀树中插入单词单词
int n=word。大小(;
特里节点*当前节点=根
for(int
I=0;I n;我)
{
如果(!currentNode-next[word[i] - a])
{
当前节点-next[word[I]- a ]=new TrieNode(word[I]);
}
当前节点=当前节点-下一个[word[I]-a ];
}
当前节点-is word=true;
}
/**如果单词在单词查找树中,则返回。*/
布尔搜索(字符串词){ //搜索树中是否存在单词单词
int n=word。size();
特里节点*当前节点=根
for(int I=0;I n;我)
{
int index=word[I]- a ;
如果(当前节点-下一个[索引])
{
当前节点=当前节点-下一个[索引];
}
其他
{
返回错误的
}
}
返回当前节点-是word
}
string startsWith(string word,int nWord) {
特里节点*当前节点=根
字符串结果;
for(int I=0;我发誓。size();我)
{
int count=0;
//统计每个节点下有多少个有效节点
for(int j=0;j 26j)
{
如果(当前节点-下一个[j])
{
数数;
}
}
if (count==1)
{
result=word.substr(0,I 1);
}
其他
{
打破;
}
if(当前节点-下一个[word[I]- a ]-is word)//当前缀树某一节点是单词的标志时即停止查找
{
打破;
}
当前节点=当前节点-下一个[word[I]-a ];
}
返回结果;
}
//14最长公共前缀
字符串longestCommonPrefix(向量字符串strs){
int n=strs。size();
如果(n==0)
{
返回"";//当输入数组为空时,返回空字符串
}
for(int I=0;I n;我)
{
if (strs[i].size()==0) //数组中某一字符串为空时,则返回空字符串
返回"";
insert(strs[I]);//前缀树的特点:在查询前先插入字符串
}
string result=以(strs[0],n)开头;//查询过程
返回结果;
}
};
注:由于测试用例比较丰富,故程序逻辑应该更加严谨,考虑更多可能出现的情况
最后附上测试结果
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。