LeetCode 第14题:最长公共前缀
1.LeetCode 第10题:正则表达式匹配2.LeetCode 第1题:两数之和3.LeetCode 第2题:两数相加4.LeetCode 第3题:无重复字符的最长子串5.LeetCode 第4题:寻找两个正序数组的中位数6.LeetCode 第8题:字符串转换整数 (atoi)7.LeetCode 第7题:整数反转8.LeetCode 第6题:Z字形变换9.LeetCode 第5题:最长回文子串10.LeetCode 第9题:回文数11.LeetCode 第11题:盛最多水的容器12.LeetCode 第12题:整数转罗马数字13.LeetCode 第13题:罗马数字转整数
14.LeetCode 第14题:最长公共前缀
15.LeetCode 第15题:三数之和16.LeetCode 第16题:最接近的三数之和17.LeetCode 第17题:电话号码的字母组合18.LeetCode 第18题:四数之和19.LeetCode 第19题:删除链表的倒数第N个结点20.LeetCode 第20题:有效的括号21.LeetCode 第21题:合并两个有序链表22.LeetCode 第22题:括号生成23.LeetCode 第23题:合并K个升序链表24.LeetCode 第24题:两两交换链表中的节点25.LeetCode 第25题:K 个一组翻转链表26.LeetCode 第26题:删除有序数组中的重复项27.LeetCode 第27题:移除元素28.LeetCode 第28题:找出字符串中第一个匹配项的下标29.LeetCode 第29题:两数相除30.LeetCode 第30题:串联所有单词的子串31.LeetCode 第31题:下一个排列32.LeetCode 第32题:最长有效括号33.LeetCode 第33题:搜索旋转排序数组34.LeetCode 第34题:在排序数组中查找元素的第一个和最后一个位置35.LeetCode 第35题:搜索插入位置36.LeetCode 第36题:有效的数独37.LeetCode 第37题:解数独38.LeetCode 第38题:外观数列39.LeetCode 第39题:组合总和40.LeetCode 第40题:组合总和 II41.LeetCode 第41题:缺失的第一个正数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] 仅由小写英文字母组成
解题思路
方法一:横向扫描
从前往后扫描所有字符串的每一个字符,直到遇到不同的字符。
关键点:
- 以第一个字符串为基准
- 依次与其他字符串比较
- 遇到不同字符或某个字符串结束时停止
具体步骤:
- 如果字符串数组为空,返回空字符串
- 取第一个字符串作为初始前缀
- 依次与其他字符串比较,更新最长公共前缀
- 如果中途前缀变为空,直接返回
时间复杂度:O(S),S是所有字符串中字符总数
空间复杂度:O(1)
方法二:纵向扫描
逐位比较所有字符串的相同位置的字符。
具体步骤:
- 从位置0开始
- 比较所有字符串在该位置的字符
- 如果都相同,继续下一位
- 如果不同或超出某个字符串长度,返回当前结果
代码实现
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();
}
}
代码详解
横向扫描版本:
- 特殊情况处理:
- 检查数组是否为空
- 前缀更新:
- 使用IndexOf检查是否为前缀
- 不断缩短前缀直到匹配
- 提前返回:
- 当前缀为空时直接返回
纵向扫描版本:
- 获取最短长度:
- 避免越界访问
- 逐位比较:
- 使用StringBuilder提高效率
- 遇到不同字符立即返回
- 优化处理:
- 只需扫描到最短字符串的长度
执行结果
横向扫描版本:
- 执行用时:92 ms
- 内存消耗:37.5 MB
纵向扫描版本:
- 执行用时:88 ms
- 内存消耗:37.8 MB
总结与反思
- 这道题的关键点:
- 理解公共前缀的概念
- 选择合适的扫描方式
- 处理边界情况
- 两种解法比较:
- 横向扫描:实现简单,但可能重复扫描
- 纵向扫描:效率更高,但需要额外空间
- 优化思路:
- 可以先排序,只需比较第一个和最后一个字符串
- 使用分治法可以优化大规模数据
- 二分查找也是一种可行的优化方案
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了