自学内容网 自学内容网

LeetCode【0014】最长公共前缀

1 中文题目

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

示例 :

输入:strs = ["flower","flow","flight"]
输出:"fl"
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

提示:

  • 1 ≤ s t r s . l e n g t h ≤ 200 1 \leq strs.length \leq 200 1strs.length200
  • 0 ≤ s t r s [ i ] . l e n g t h ≤ 200 0 \leq strs[i].length \leq 200 0strs[i].length200
  • s t r s [ i ] strs[i] strs[i] 仅由小写英文字母组成

2 求解思路

2.1 基础解法:排序法

思路

先对字符串数组进行字典序排序,然后只需要比较首尾两个字符串的公共前缀即可。因为字典序排序后,第一个和最后一个字符串的差异最大,它们的公共前缀一定是整个数组的公共前缀。

# 原始数组:["flower", "flow", "flight", "flake"]
sorted_strs = sorted(strs)
# 排序后:["flake", "flight", "flow", "flower"]

# 获取首尾字符串
first = "flake"
last = "flower"

Python代码

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        """
        使用排序法查找字符串数组中的最长公共前缀
        
        思路:
        1. 对字符串数组进行字典序排序
        2. 只需比较首尾两个字符串
        3. 找出它们的公共前缀即为结果
        
        参数:
            strs: 字符串数组,如 ["flower","flow","flight"]
        返回:
            最长公共前缀字符串,如 "fl"
        """
        # 处理特殊情况
        if not strs:
            return ""
        if len(strs) == 1:
            return strs[0]
        
        # 对字符串数组进行字典序排序
        # 排序后,第一个和最后一个字符串的差异最大
        sorted_strs = sorted(strs)
        
        # 获取首尾字符串
        first = sorted_strs[0]
        last = sorted_strs[-1]
        
        # 获取首尾字符串的最短长度
        min_length = min(len(first), len(last))
        
        # 查找公共前缀
        result = []
        for i in range(min_length):
            # 如果字符不同,直接返回当前累积的前缀
            if first[i] != last[i]:
                break
            result.append(first[i])
        
        # 返回找到的最长公共前缀
        return ''.join(result)

时空复杂度分析

  • 时间复杂度分析:O(nlogn + m)
    • 排序:O(nlogn),n为字符串数量
    • 比较:O(m),m为最短字符串长度
  • 空间复杂度分析:O(n + m)
    • 排序空间:O(n)
    • 结果空间:O(m)

2.2 优化解法:滑动窗口法

思路
从第一个字符开始,逐步扩展窗口大小,每次检查所有字符串在当前位置是否具有相同的字符。一旦发现不同字符,立即停止扩展并返回当前的公共前缀。

python代码

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        """
        滑动窗口法:使用逐步扩展窗口的方式
        """
        # 处理特殊情况
        if not strs:
            return ""
            
        # 初始化窗口大小为1
        prefix = ""
        min_length = min(len(s) for s in strs)
        
        # 逐步扩展窗口
        for i in range(min_length):
            current_char = strs[0][i]
            # 检查所有字符串在当前位置的字符是否相同
            if all(s[i] == current_char for s in strs):
                prefix += current_char
            else:
                break
                
        return prefix

时空复杂度分析

  • 时间复杂度分析:
    • 最好情况:O(n),n为最短字符串长度
    • 最坏情况:O(S),S为所有字符的总和
    • 平均情况:O(n×m),m为字符串个数
  • 空间复杂度分析:O(1)

2.3 最优解法:基于python内置函数的横向扫描法

思路
使用zip函数将所有字符串按位置压缩,然后逐位比较每个位置上的字符是否相同。当发现不同字符时,即可确定最长公共前缀的长度。

详细步骤解析:

  • zip函数的工作原理:
    • zip(*strs)将所有字符串解包,按位置将字符组合成元组
例如:["abc", "abd", "abf"] 转换为:
('a','a','a') # 第一位
('b','b','b') # 第二位
('c','d','f') # 第三位
  • enumerate的使用:
    • 提供当前处理的位置索引,同时获取当前位置的字符元组。i表示位置,chars表示该位置的所有字符
  • set去重判断:
    • set(chars)将字符元组转为集合,相同字符的集合长度为1,不同字符的集合长度大于1
  • 结果处理:
    • 发现不同时返回前i个字符,全部相同时返回最短字符串

示例

# 输入:strs = ["flower","flow","flight"]
# zip(*strs) 生成:
# 第1轮:('f','f','f')   # set长度为1,继续
# 第2轮:('l','l','l')   # set长度为1,继续
# 第3轮:('o','o','i')   # set长度为2,返回"fl"

python代码

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        """
        使用zip函数实现 
        
        参数:
            strs: 字符串数组
        返回:
            最长公共前缀字符串
        """
        # 处理特殊情况
        if not strs:
            return ""
            
        # 使用zip函数将所有字符串按位置打包
        for i, chars in enumerate(zip(*strs)):
            # 检查当前位置的所有字符是否相同
            if len(set(chars)) != 1:
                # 不相同时返回之前的前缀
                return strs[0][:i]
        
        # 所有字符都相同,返回最短字符串
        return min(strs, key=len)

时空复杂度分析

  • 时间复杂度分析:O(S):S是所有字符串的字符数总和
    • zip操作需要遍历所有字符
    • set操作为O(1)
    • min操作为O(n),n为字符串个数
  • 空间复杂度分析:O(1)

3 题目总结

题目难度:简单
数据结构:字符串数组
应用算法:python内置函数


原文地址:https://blog.csdn.net/qq_32882309/article/details/143712545

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!