题目链接:14. 最长公共前缀 - 力扣(LeetCode)
普通版本(横向扫描)
主旨:用第一个字符串与后续的每个字符串进行比较,先获取S1和S2的最长公共前缀,然后将该次比较获得的最长公共前缀再与下一个字符串进行比较更新,直至循环结束
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (!strs.size()) //数组为空时
{
return "";
}
string prefix = strs[0];//先获取第一个字符串
int count = strs.size();//获取数组大小
for (int i = 1; i < count; ++i)
{
prefix = judgeFunc(prefix, strs[i]);//更新每次的最长公共前缀
}
return prefix;
}
//比较函数
string judgeFunc(const string& str1, const string& str2)
{
int length = min(str1.size(), str2.size());//获取最小的那个字符串长度,即每次最大的比较字符
int index = 0;
while (index < length && str1[index] == str2[index]) //单字符相同index就++
{
++index;
}
return str1.substr(0, index);//返回一个截取(0,index)范围内的str1字符串
}
};
时间复杂度:O(mn)(其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次)
空间复杂度:O(1)
普通版本(纵向扫描)
主旨:从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (!strs.size())
{
return "";
}
//纵向扫描不需要存储
int length = strs[0].size();//获取数组第一个字符串的长度
int count = strs.size();//获取整个数组的长度
for (int i = 0; i < length; ++i)
{
char c = strs[0][i];//获取第0行第i列上的字符
for (int j = 1; j < count; ++j) //便利了
{
if ( i == strs[j].size() || strs[j][i] != c) //当已经遍历到某个字符串的末尾(遍历第i列时,等于了某一行字符串的长度strs[j].size) 或 第j行的第i列不等于c
{
return strs[0].substr(0, i);//返回第一个字符串0~i范围内的字符
}
}
}
return strs[0];//如果每一列的元素都一样,就返回数组的第一个字符串
}
};
- 时空复杂度同上
优化版本(分治,待补充)
优化版本(二分查找,待补充)
~over~