【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/

相关推荐
self_myth3 小时前
算法与数据结构实战技巧:从复杂度分析到数学优化
算法
songx_993 小时前
leetcode10(跳跃游戏 II)
数据结构·算法·leetcode
先做个垃圾出来………4 小时前
差分数组(Difference Array)
java·数据结构·算法
hansang_IR4 小时前
【题解】洛谷 P4286 [SHOI2008] 安全的航线 [递归分治]
c++·数学·算法·dfs·题解·向量·点积
乐迪信息4 小时前
乐迪信息:AI摄像机在智慧煤矿人员安全与行为识别中的技术应用
大数据·人工智能·算法·安全·视觉检测
多恩Stone5 小时前
【3DV 进阶-2】Hunyuan3D2.1 训练代码详细理解下-数据读取流程
人工智能·python·算法·3d·aigc
惯导马工6 小时前
【论文导读】IDOL: Inertial Deep Orientation-Estimation and Localization
深度学习·算法
老姜洛克6 小时前
自然语言处理(NLP)之n-gram从原理到实战
算法·nlp
1白天的黑夜16 小时前
哈希表-49.字母异位词分组-力扣(LeetCode)
c++·leetcode·哈希表