LeetCode 第14题:最长公共前缀

LeetCode 第14题:最长公共前缀

题目描述

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

难度

简单

题目链接

https://leetcode.cn/problems/longest-common-prefix/

示例

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:

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

提示

  • 1 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] 仅由小写英文字母组成

解题思路

方法一:横向扫描

从前往后扫描所有字符串的每一个字符,直到遇到不同的字符。

关键点:

  1. 以第一个字符串为基准
  2. 依次与其他字符串比较
  3. 遇到不同字符或某个字符串结束时停止

具体步骤:

  1. 如果字符串数组为空,返回空字符串
  2. 取第一个字符串作为初始前缀
  3. 依次与其他字符串比较,更新最长公共前缀
  4. 如果中途前缀变为空,直接返回

时间复杂度:O(S),S是所有字符串中字符总数
空间复杂度:O(1)

方法二:纵向扫描

逐位比较所有字符串的相同位置的字符。

具体步骤:

  1. 从位置0开始
  2. 比较所有字符串在该位置的字符
  3. 如果都相同,继续下一位
  4. 如果不同或超出某个字符串长度,返回当前结果

代码实现

C# 实现(横向扫描)

public class Solution {
    public string LongestCommonPrefix(string[] strs) {
        if (strs == null || strs.Length == 0) {
            return "";
        }
      
        // 以第一个字符串为基准
        string prefix = strs[0];
      
        // 依次与其他字符串比较
        for (int i = 1; i < strs.Length; i++) {
            // 更新最长公共前缀
            while (strs[i].IndexOf(prefix) != 0) {
                prefix = prefix.Substring(0, prefix.Length - 1);
                if (prefix.Length == 0) {
                    return "";
                }
            }
        }
      
        return prefix;
    }
}

C# 实现(纵向扫描)

public class Solution {
    public string LongestCommonPrefix(string[] strs) {
        if (strs == null || strs.Length == 0) {
            return "";
        }
      
        // 获取最短字符串的长度
        int minLength = strs[0].Length;
        foreach (string str in strs) {
            minLength = Math.Min(minLength, str.Length);
        }
      
        // 逐位比较
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < minLength; i++) {
            char currentChar = strs[0][i];
          
            // 检查所有字符串的当前位置
            for (int j = 1; j < strs.Length; j++) {
                if (strs[j][i] != currentChar) {
                    return result.ToString();
                }
            }
          
            result.Append(currentChar);
        }
      
        return result.ToString();
    }
}

代码详解

横向扫描版本:

  1. 特殊情况处理:
    • 检查数组是否为空
  2. 前缀更新:
    • 使用IndexOf检查是否为前缀
    • 不断缩短前缀直到匹配
  3. 提前返回:
    • 当前缀为空时直接返回

纵向扫描版本:

  1. 获取最短长度:
    • 避免越界访问
  2. 逐位比较:
    • 使用StringBuilder提高效率
    • 遇到不同字符立即返回
  3. 优化处理:
    • 只需扫描到最短字符串的长度

执行结果

横向扫描版本:

  • 执行用时:92 ms
  • 内存消耗:37.5 MB

纵向扫描版本:

  • 执行用时:88 ms
  • 内存消耗:37.8 MB

总结与反思

  1. 这道题的关键点:
    • 理解公共前缀的概念
    • 选择合适的扫描方式
    • 处理边界情况
  2. 两种解法比较:
    • 横向扫描:实现简单,但可能重复扫描
    • 纵向扫描:效率更高,但需要额外空间
  3. 优化思路:
    • 可以先排序,只需比较第一个和最后一个字符串
    • 使用分治法可以优化大规模数据
    • 二分查找也是一种可行的优化方案

相关题目

posted @   旧厂街小江  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示