最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入:strs = ["flower","flow","flight"] 输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"] 输出:"" 解释:输入不存在公共前缀。
实现思路:
本题是为了求一个字符串数组的最长公共前缀,我们可以试着让第一个字符串,作为公共前缀字符串,与其他的字符串进行比对,如果公共前缀的字符在与其他字符串字符不同时,则缩减前缀字符串,缩减为0时,则返回空字符串。
注意,我这里的判断条件是,当前前缀字符串的字符与比对的字符是否相同,不同时做处理,相同时则不做处理。
实现代码:
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
// 取数组的第一个字符串作为初始的最长公共前缀
String prefix = strs[0];
// 遍历字符串数组
for (String str : strs) {
while (!str.startsWith(prefix)) {
// 如果当前字符串不以prefix开头,缩短prefix
prefix = prefix.substring(0, prefix.length() - 1);
// 如果缩短到空字符串,直接返回
if (prefix.isEmpty()) {
return "";
}
}
}
return prefix;
}
思路模拟详解:
-
检查空数组或null:
- 如果
strs
是null
或者长度为0,直接返回空字符串""
。
- 如果
-
初始化前缀:
- 选择数组的第一个元素
strs[0]
作为初始的最长公共前缀prefix
。
- 选择数组的第一个元素
-
遍历数组:
- 使用增强型for循环遍历数组
strs
中的每个字符串str
。
- 使用增强型for循环遍历数组
-
检查公共前缀:
- 对于数组中的每个字符串
str
,使用startsWith
方法检查它是否以当前的prefix
作为前缀。
- 对于数组中的每个字符串
-
更新前缀:
- 如果
str
不以prefix
开头,说明prefix
太长了。使用substring
方法缩短prefix
,去掉最后一个字符,然后再次检查。 - 这个过程会一直重复,直到
prefix
缩短到所有字符串都以它为前缀,或者prefix
为空。
- 如果
-
结束条件:
- 如果在任何时候
prefix
被缩短到空字符串,说明数组中的字符串没有公共前缀,此时直接返回""
。
- 如果在任何时候
-
返回结果:
- 循环结束后,
prefix
就是所有字符串的最长公共前缀,返回这个值。
- 循环结束后,
示例1模拟:
- 输入:
strs = {"flower", "flow", "flight"}
- 初始化
prefix
为"flower"
。 - 第一轮for循环:prefix(flower)等于flower,结束循环
- 第二轮for循环:prefix(" flower ")不等于" flow " ,进入while循环,prefix缩减一个字符 ,更新prefix为" flowe ",进行第二轮while循环判断,prefix(" flowe ")不等于" flow ",缩减一个字符,prefix更新为flow。再一次进行while判断,prefix(" flow ")等于flow,循环结束。
- 第三轮for循环,重复上述第二轮的过程,得到公共字符串" fl "。
- 返回
prefix
,即"
fl"
。
这里用到了String类的几个方法,下面进行补充,忘记的朋友可以进行复习。
1.startsWith
startsWith
是 String
类的一个方法,用于检查字符串是否以指定的前缀开始。如果调用对象(即 this
字符串)从开头开始就是按照指定的字符串(前缀)顺序出现的,那么返回 true
;否则返回 false
。
以下是 startsWith
方法的一些关键点:
- 方法签名:
public boolean startsWith(String prefix)
- 参数:
prefix
是一个String
类型的参数,表示要检查的前缀。 - 返回值:返回一个
boolean
值,如果调用对象以指定的前缀开始,则返回true
,否则返回false
。 - 异常:如果参数
prefix
是null
,则抛出NullPointerException
。
startsWith
方法有几个重载版本,允许你指定额外的参数来控制比较的开始位置和长度:
startsWith(String prefix)
:检查整个字符串是否以指定的前缀开始。startsWith(String prefix, int toffset)
:从指定的位置toffset
开始检查字符串,看它是否以指定的前缀开始。
2.substring
substring
是 String
类的一个方法,用于返回字符串的一个子部分,即子字符串。你可以指定一个或两个参数来确定要提取的子字符串的起始位置和结束位置(不包括结束位置的字符)。
以下是 substring
方法的一些关键点:
-
方法签名:
public String substring(int beginIndex)
:返回从beginIndex
位置开始到原字符串末尾的子字符串。public String substring(int beginIndex, int endIndex)
:返回从beginIndex
位置开始到endIndex
前一个位置的子字符串。
-
参数:
beginIndex
:子字符串的起始位置(包含该位置的字符)。endIndex
:子字符串的结束位置(不包含该位置的字符)。
-
返回值:返回一个新的
String
对象,包含提取的子字符串。 -
异常:
- 如果
beginIndex
小于 0 或大于字符串的长度,抛出StringIndexOutOfBoundsException
。 - 如果
beginIndex
大于endIndex
,抛出StringIndexOutOfBoundsException
。
- 如果
3.增强for循环
在Java中,for (String str : strs)
是一个增强型for循环(也称为for-each循环),用于遍历字符串数组 strs
中的每个元素。这种循环结构使得遍历数组和集合变得更加简洁和易于阅读。
以下是对这种循环用法的详细说明:
for
:这是Java中的循环关键字,用于开始一个for循环。(String str)
:这是循环中变量的声明部分。在每次迭代中,str
都会被赋值为数组中的当前元素。这里的String
表示数组元素的类型。:
:这个冒号与前面的变量声明一起,用于指明这是一个增强型for循环。strs
:这是要遍历的数组或集合。在这个例子中,strs
是一个字符串数组。System.out.println(str)
:这是循环体,用于执行一些操作。在这个例子中,它将打印出数组中的每个字符串。
示例代码:
String[] strs = {"apple", "banana", "cherry"}; // 遍历字符串数组
for (String str : strs)
{
System.out.println(str);
}
这段代码将输出:
apple
banana
cherry