最长公共前缀
- 标签:字符串处理、前缀判断
题目
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
提示:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成
原题:LeetCode 14
思路及实现
方式一:横向扫描
思路
代码实现
Java版本
class Solution {
public String longestCommonPrefix(String[] strs) {
// 如果字符串数组为空或者长度为0,则返回空字符串
if (strs == null || strs.length == 0) {
return "";
}
// 将第一个字符串作为前缀进行初始化
String prefix = strs[0];
// 数组中字符串的数量
int count = strs.length;
// 遍历字符串数组,依次求取最长公共前缀
for (int i = 1; i < count; i++) {
prefix = longestCommonPrefix(prefix, strs[i]);
// 如果最长公共前缀为空,则可以提前结束循环
if (prefix.length() == 0) {
break;
}
}
// 返回最长公共前缀
return prefix;
}
// 求取两个字符串的最长公共前缀
public String longestCommonPrefix(String str1, String str2) {
// 获取两个字符串的最小长度
int length = Math.min(str1.length(), str2.length());
// 初始化索引
int index = 0;
// 遍历两个字符串,找到最长公共前缀的结束索引
while (index < length && str1.charAt(index) == str2.charAt(index)) {
index++;
}
// 返回最长公共前缀
return str1.substring(0, index);
}
}
说明:
首先,通过判断字符串数组strs是否为空或长度为0,来确定是否存在最长公共前缀。如果数组为空或长度为0,则直接返回空字符串。
将字符串数组中的第一个字符串作为初始化的最长公共前缀prefix。
使用一个循环遍历剩余的字符串,依次计算最长公共前缀。在每次循环中,调用longestCommonPrefix()方法,将当前最长公共前缀prefix和当前遍历的字符串进行比较,更新最长公共前缀。
如果最长公共前缀为空字符串,则说明不存在公共前缀,无需继续循环,直接跳出。 最后,返回最长公共前缀prefix。
longestCommonPrefix()方法是一个内部方法,用于找到两个字符串str1和str2的最长公共前缀。
首先,获取两个字符串的最小长度length。 初始化索引index为0。
遍历两个字符串,比较对应位置的字符是否相等,直到遇到不相等的字符或到达较短字符串的末尾。
最后,返回前缀部分的字符串,即str1中的前index个字符。
C语言版本
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* longestCommonPrefix(char** strs, int strsSize) {
// 如果字符串数组为空或者长度为0,则返回空字符串
if (strs == NULL || strsSize == 0)
return "";
// 将第一个字符串作为初始的最长公共前缀
char* prefix = strs[0];
// 遍历数组剩余的字符串,更新最长公共前缀
for (int i = 1; i < strsSize; i++) {
prefix = lcp(prefix, strs[i]);
// 如果最长公共前缀为空,则跳出循环
if (prefix[0] == '\0')
break;
}
return prefix;
}
说明:
longestCommonPrefix() 函数用于找到字符串数组 strs 中的最长公共前缀。
首先,判断字符串数组是否为空或长度为0,如果是,则直接返回空字符串。 将数组的第一个字符串作为初始的最长公共前缀 prefix。
遍历数组剩余的字符串,调用 lcp() 函数计算当前字符串与当前最长公共前缀的公共前缀,并更新最长公共前缀 prefix。
如果最长公共前缀为空字符串,则无需继续遍历,跳出循环。 返回最长公共前缀 prefix。 lcp() 函数用于找到两个字符串 str1 和str2 的最长公共前缀。 获取两个字符串的最小长度 length。 初始化索引 index 为0。
遍历两个字符串,比较对应位置的字符是否相等,直到遇到不相等的字符或到达较短字符串的末尾。 创建一个新的字符串来存储最长公共前缀commonPrefix。
使用 strncpy() 函数从 str1 复制 index 个字符到 commonPrefix 中。 在
commonPrefix 的末尾添加字符串结束符 ‘\0’。 返回最长公共前缀 commonPrefix。
Python3版本
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
# 如果字符串数组为空,则返回空字符串
if not strs:
return ""
# 将数组的第一个字符串作为初始的最长公共前缀
prefix, count = strs[0], len(strs)
# 遍历数组剩余的字符串,更新最长公共前缀
for i in range(1, count):
prefix = self.lcp(prefix, strs[i])
# 如果最长公共前缀为空,则跳出循环
if not prefix:
break
return prefix
# 求取两个字符串的最长公共前缀
def lcp(self, str1, str2):
# 获取两个字符串的最小长度
length, index = min(len(str1), len(str2)), 0
# 遍历两个字符串,找到最长公共前缀的结束索引
while index < length and str1[index] == str2[index]:
index += 1
# 返回最长公共前缀
return str1[:index]
说明:
longestCommonPrefix()方法是一个类方法,用于找到字符串数组strs中的最长公共前缀。
首先,判断字符串数组是否为空,如果为空,则直接返回空字符串。 将数组的第一个字符串作为初始的最长公共前缀 prefix。
获取数组中的字符串数量 count。 使用一个循环遍历剩余的字符串,调用 lcp()
方法来计算当前字符串与当前最长公共前缀的公共前缀,并更新最长公共前缀 prefix。 如果最长公共前缀为空字符串,则无需继续遍历,跳出循环。
返回最长公共前缀 prefix。 lcp() 方法是一个类方法,用于找到两个字符串 str1 和 str2 的最长公共前缀。
获取两个字符串的最小长度 length。 初始化索引 index 为0。
遍历两个字符串,比较对应位置的字符是否相等,直到遇到不相等的字符或到达较短字符串的末尾。 返回前缀部分的字符串,即 str1 中的前
index 个字符。
复杂度分析
- 时间复杂度:O(mn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次。
- 空间复杂度:O(1)。使用的额外空间复杂度为常数。
方式二:纵向扫描
思路
方法一是横向扫描,依次遍历每个字符串,更新最长公共前缀。另一种方法是纵向扫描。纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。
代码实现
Java版本
class Solution {
public String longestCommonPrefix(String[] strs) {
// 如果字符串数组为空或者长度为0,直接返回空字符串
if (strs == null || strs.length == 0) {