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

相关推荐
小白程序员成长日记4 分钟前
2025.12.01 力扣每日一题
算法·leetcode·职场和发展
爱装代码的小瓶子4 分钟前
【cpp知识铺子】map和set的前身-二叉搜索树
c++·算法
TL滕37 分钟前
从0开始学算法——第四天(练点题吧)
数据结构·笔记·学习·算法
[J] 一坚39 分钟前
华为OD、微软、Google、神州数码、腾讯、中兴、网易有道C/C++字符串、数组、链表、树等笔试真题精粹
c语言·数据结构·c++·算法·链表
多则惑少则明42 分钟前
【算法题4】找出字符串中的最长回文子串(Java版)
java·开发语言·数据结构·算法
迷途之人不知返1 小时前
二叉树题目
数据结构·算法
优宁维生物2 小时前
DNA 提取的基础方法
人工智能·算法
@Aurora.2 小时前
优选算法【专题二:滑动窗口】
算法
小石头 100862 小时前
【Java】String类(超级详细!!!)
java·开发语言·算法
.柒宇.2 小时前
力扣hot100---42.接雨水(java版)
java·算法·leetcode