最长公共前缀
1>题目描述
-
编写一个函数来查找字符串数组中的最长公共前缀。
-
如果不存在公共前缀,返回空字符串 “”。
示例 1: 输入:strs = ["flower","flow","flight"] 输出:"fl" 示例 2: 输入:strs = ["dog","racecar","car"] 输出:"" 解释:输入不存在公共前缀。
2>纵向查找(第一想法)
- 1>我们首先知道若要寻找最长公共前缀,必然从起点开始。
- 2>最长公共前缀必然小于等于字符串数组中的最短字符串长度。
2.1、代码思路
- 1、取字符串数组中第一个字符串的长度,作为for循环遍历的条件
- 2、通过字符串数组遍历每一个字符串
- 3、终止条件:
- 1、某个字符与第一个字符串对应索引的字符不同,立刻终止循环,输出最长公共前缀。
- 2、 循环过程中超过了某个字符串的最大长度,说明该字符串即是最长公共前缀。
4、特殊情况:若字符串数组仅有一个字符串,则直接将它输出。
2.2、代码实现
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs == null||strs.length ==0){
return "";
}
int length = strs[0].length();
for(int i=0;i<length;i++){
char value = strs[0].charAt(i);
for(int j=1;j<strs.length;j++){
if(i == strs[j].length()||value!=strs[j].charAt(i))
return strs[0].substring(0,i);
}
}
return strs[0];
}
}
2.3、复杂度分析
- 时间复杂度:O(mn),其中 m 是字符串数组中的字符串的平均长度,n是字符串的数量。最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次。
- 空间复杂度:O(1)O(1)。使用的额外空间复杂度为常数
3>横向查找
- 也就是说我们可以两两查找字符串,并得到两个字符串的最长公共前缀并与后面的字符串进行比较
3.1、代码思路
- 1>可以利用递归的思想,返回两个字符串的最长公共前缀,让其与后一个字符串进行比较。
- 2>若在过程中,最长公共前缀变为0,那么直接输出"",否则遍历完所有字符串的时候,输出的公共前缀便为正确值。
3.2、代码实现
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length == 0){
return "";
}
String s = strs[0];
for(int i=1;i<strs.length;i++){
s = longestCommonPrefix(s,strs[i]);
if(s == ""){
return "";
}
}
return s;
}
public String longestCommonPrefix(String strs1,String strs2){
int length = Math.min(strs1.length(),strs2.length());
int index = 0;
while(index != length&&strs1.charAt(index)==strs2.charAt(index))
{
index++;
}
return strs1.substring(0,index);
}
}
3.3、复杂度分析
- 时间复杂度:O(mn),其中 m 是字符串数组中的字符串的平均长度,n是字符串的数量。最坏情况下,字符串数组中的每个字符串的每个字符都会被比较一次。
- 空间复杂度:O(1)。使用的额外空间复杂度为常数
4>分治
4.1、代码思路
- 1>这里的递归用法,类似于归并排序,同样适用分治
- 2>通过递归将字符串数组分到直到两个字符串,然后开始开始合并,之后的每一层递归都对两个字符串进行最长公共前缀的查找,直到返回第一层。
4.2、代码实现
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length == 0){
return "";
}
return longestCommonPrefix(strs,0,strs.length-1);
}
public String longestCommonPrefix(String[] strs,int left,int right){
if(left == right){
return strs[left];
}
int mid = (left+right)/2;
String s1 = longestCommonPrefix(strs,left,mid);
String s2 = longestCommonPrefix(strs,mid+1,right);
return CompareString(s1,s2);
}
public String CompareString(String s1,String s2){
int index = 0;
int length = Math.min(s1.length(),s2.length());
while(index != length&&s1.charAt(index)==s2.charAt(index)){
index++;
}
return s1.substring(0,index);
}
}
4.3、复杂度分析
- 时间复杂度:O(mn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。时间复杂度的递推式是 T(n)=2⋅T(n/2)+O(m),通过计算可得 T(n)=O(mn)。
- 空间复杂度:O(mlogn),其中 m 是字符串数组中的字符串的平均长度,n 是字符串的数量。空间复杂度主要取决于递归调用的层数,层数最大为logn,每层需要 m 的空间存储返回结果。
5>二分查找
- 还没实现,之后在写