题意思路:

题目给出长度为n的子串,找出子串中最长的公共前缀。

方法一:子串纵向查找

纵向遍历非常的直观,如下图所示,将每个字符串分别依次遍历每一列的元素,比较相同列上字符是否相同,若相同则比较下一个子串,若不同则最长公共前缀为上个遍历过的公共前缀。

复杂度分析:
时间复杂度:O(mn),其中n 是字符串的数量,m 是字符串数组中的字符串的平均长度。最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次。

空间复杂度:O(1)。额外空间复杂度为常数。

演示子串纵向查找方式:
算法演示图

class Solution {
public:

    string longestCommonPrefix(vector<string>& strs) {
        // write code here
        if(!strs.size())return "";//特判若子串为空则返回空值
        for(int i=0;i<strs[0].size();i++){//枚举第一个子串的每个字符
            for(int j=1;j<strs.size();j++){//枚举后面所有子串
                if(strs[0][i]!=strs[j][i]||i==strs[j].size()){//比较后面所有子串的第i列字符和第j个子串的长度
                    return strs[0].substr(0,i);//若字符不相同或者长度为最小则返回最长公共前缀
                }
            }
        }
        return strs[0];
    }
};

方法二:排序后子串纵向查找

先将所以子字符串按照字典序的大小排序,想要得到最长公共前缀,只需要将字典序最小的子串A与字典序最大的B比较相同部分,得到的最长公共前缀就是所有子串的公共前缀。

复杂度分析:

时间复杂度:O(nlogn),其中n 是字符串的数量,排序算法时间复杂度O(nlogn)。

空间复杂度:O(1)。额外空间复杂度为常数。

class Solution {
public:

    string longestCommonPrefix(vector<string>& strs) {
         if(!strs.size())return "";
         sort(strs.begin(),strs.end());//按照字典序排序得到所有子串顺序
         string a=strs.front(),b=strs.back();//枚举第一个最小的子串和最后一个最大的子串
         int i=0;
         for(i=0;i<a.size()&&a[i]==b[i];i++);//若字符相同则继续比较否则返回最长公共前缀串
         return a.substr(0,i);

    }
};