【LeetCode】14. 最长公共前缀

文章目录

【题目链接】

14. 最长公共前缀

【题目描述】

【思路一:横向扫描】

以第一个字符串为基准,依次遍历数组中每个字符串,更新最长公共前缀

Python实现:

python 复制代码
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if not strs:
            return " "

        prefix = strs[0]
        
        for i in range(1, len(strs)):
            prefix = self.merge(prefix, strs[i])
            if not prefix:
                break

        return prefix

    def merge(self, str1, str2) -> str:
        length = min(len(str1), len(str2))
        index = 0

        for i in range(0 ,length):
            if str1[i] != str2[i]:
                break
            index += 1

        return str1[:index]

C++实现:

cpp 复制代码
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        
        if (strs.size() == 0){
            return "";
        }

        string prefix = strs[0];
        int count = strs.size();

        for (int i=0; i<count; i++){
            prefix = merge(prefix, strs[i]);
            if (prefix.size()==0){
                break;
            }
        }

        return prefix;
    }

    string merge(const string& str1, const string& str2){
        int length = min(str1.size(), str2.size());
        int index = 0;

        for (int i=0; i<length; i++){
            if (str1[i] != str2[i]){
                break;
            }

            index++;
        }

        return str1.substr(0, index);
    }
};

时间复杂度分析:

设字符串数组 strs 的长度为 n(即有n个字符串)

设数组中最短字符串的长度为 m

总时间复杂度:O(nm),因为在最坏情况下(所有字符串都相同),需要将每个字符串的每个字符都比较一次,总比较次数为 n×m

空间复杂度分析:

空间复杂度为O(m), 即第一个字符串的长度

【思路二:纵向扫描】

纵向扫描,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀

解题示意图:

C++ 实现

cpp 复制代码
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if (strs.size()==0){
            return " ";
        }

        int length = strs[0].size();
        int count = strs.size();

        for (int i=0; i<length; i++){
            
            char c = strs[0][i];

            for (int j=0; j<count; j++){
                if (i==strs[j].size() || strs[j][i] != c){
                    return strs[0].substr(0,i);
                }
            }
        }

        return strs[0];
    }
};

Python 实现

python 复制代码
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if not strs:
            return ""

        length = len(strs[0])
        count = len(strs)

        for i in range(0, length):
            char = strs[0][i]

            for j in range(1, count):
                if i == len(strs[j]) or char != strs[j][i]:
                    return strs[0][0:i]
        
        return strs[0]

时间复杂度分析:

O(mn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。

最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次

空间复杂度分析:

代码中只使用了几个额外变量

这些变量的空间占用不随输入规模(字符串数量或长度)变化,都是常数级

没有使用额外的数组、列表等数据结构

因此,空间复杂度为 O(1)

【思路三:分治】

基本思路:

C++ 代码实现:

cpp 复制代码
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if (strs.size() == 0){
            return "";
        }
        else{
            return longestCommonPrefix(strs, 0, strs.size()-1);
        }
    }

    string longestCommonPrefix(const vector<string>& strs, int start, int end){
        if(start == end){
            return strs[start];
        }
        else{
            int mid = (start+end)/2;
            string lcpLeft = longestCommonPrefix(strs, start, mid);
            string lcpRight = longestCommonPrefix(strs, mid+1, end);

            return commonPrefix(lcpLeft, lcpRight);
        }
    }

    string commonPrefix(const string& lcpLeft, const string& lcpRight){
        int minLength = min(lcpLeft.size(), lcpRight.size());

        for(int i=0; i<minLength; i++){
            if (lcpLeft[i] != lcpRight[i]){
                return lcpLeft.substr(0, i);
            }
        }

        return lcpLeft.substr(0, minLength);
    }
};

Python实现:

python 复制代码
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        def lcp(start,end):
            if start==end:
                return strs[start]
            
            mid = (start+end) //2
            lcpLeft = lcp(start, mid)
            lcpRight = lcp(mid+1, end)

            minLength = min(len(lcpLeft), len(lcpRight))

            for i in range(0, minLength, 1):
                if lcpLeft[i] != lcpRight[i]:
                    return lcpLeft[:i]

            return lcpLeft[: minLength]
        
        return "" if not strs else lcp(0, len(strs)-1)

时间复杂度: O(mn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。

空间复杂度: O(mlogn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。空间复杂度主要取决于递归调用的层数,层数最大为 logn,每层需要 m 的空间存储返回结果。

参考链接: https://leetcode.cn/problems/longest-common-prefix/solutions/288575/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/

相关推荐
会员源码网11 小时前
使用`mysql_*`废弃函数(PHP7+完全移除,导致代码无法运行)
后端·算法
木心月转码ing12 小时前
Hot100-Day10-T438T438找到字符串中所有字母异位词
算法
HelloReader12 小时前
Wi-Fi CSI 感知技术用无线信号“看见“室内的人
算法
颜酱15 小时前
二叉树分解问题思路解题模式
javascript·后端·算法
qianpeng89716 小时前
水声匹配场定位原理及实验
算法
董董灿是个攻城狮1 天前
AI视觉连载8:传统 CV 之边缘检测
算法
AI软著研究员1 天前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish1 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱2 天前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
地平线开发者2 天前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶