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

相关推荐
小欣加油2 小时前
leetcode 1863 找出所有子集的异或总和再求和
c++·算法·leetcode·职场和发展·深度优先
十八岁讨厌编程2 小时前
【算法训练营Day27】动态规划part3
算法·动态规划
炬火初现3 小时前
Hot100-哈希,双指针
算法·哈希算法·散列表
weixin_307779133 小时前
利用复变函数方法计算常见函数的傅里叶变换
算法
来不及辣哎呀4 小时前
苍穹外卖项目面试总结话术
面试·职场和发展
共享家95274 小时前
LeetCode热题100(1-7)
算法·leetcode·职场和发展
新学笺5 小时前
数据结构与算法 —— Java单链表从“0”到“1”
算法
同元软控5 小时前
首批CCF教学案例大赛资源上线:涵盖控制仿真、算法与机器人等9大方向
算法·机器人·工业软件·mworks
yiqiqukanhaiba6 小时前
Linux编程笔记2-控制&数组&指针&函数&动态内存&构造类型&Makefile
数据结构·算法·排序算法
PKNLP6 小时前
逻辑回归(Logistic Regression)
算法·机器学习·逻辑回归