题目描述(简单难度)
编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。
解法一 垂直比较
Java
思路:我们首先判定给定数组中长度最小的元素,然后按照这个min(length)
,将数组中元素依次进行比较,如果比较成功返回True
,不成功则返回Fasle
.
public String longestCommonPrefix(String[] strs) {
if (strs.length==0) return "";
if (strs.length==1) return strs[0].substring(0);
int min = Integer.MAX_VALUE;
for (int i = 0;i<strs.length;i++) {
if(strs[i].length()<min) {
min=strs[i].length();
}
}
int i = 0;
for (;i<min;i++){
if(!is_same(strs,i)) break;
}
return strs[0].substring(0,i);
}
public boolean is_same(String[] strs,int i){
int m=0;
for(int j=0;j<strs.length-1;j++){
if(strs[j].charAt(i)==strs[j+1].charAt(i)){
m++;
}else{
return false;
}
}
return true;
}
public static void main(String args[]) {
String[] s= {"flower","flow","flight"};
String ans=longestcommen(s);
System.out.println(ans);
}
}
Python
class Solution(object):
def longestCommonPrefix(self, strs):
if len(strs)==0:
return ""
min = sys.maxint
for i in range(len(strs)):
if len(strs[i]) < min:
min=len(strs[i])
s=0
for j in range(0,min):
if(self.is_same(strs,j)):
s+=1
else:
break
return strs[0][0:s]
def is_same(self,strs,i):
m=0
for k in range(len(strs)-1):
if(strs[k][i]==strs[k+1][i]):
m+=1
else:
return False
return True
解法二 水平比较
我们将字符串水平排列,寻找第0 个和第 1 个字符串的最长子串,结果为 fl,再把结果和第 2 个字符串比较,结果为 fi,即为最终结果。
Java
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0) return "";
String prefix = strs[0];
for (int i = 1; i < strs.length; i++) {
int minLen = Math.min(prefix.length(), strs[i].length());
int j = 0;
for (; j < minLen; j++) {
if (prefix.charAt(j) != strs[i].charAt(j)) {
break;
}
}
prefix = prefix.substring(0, j);
}
return prefix;
}
}
时间复杂度:最坏情况和解法一是一样,n 个长度为 m 的完全相同的字符,就要比较所有的字符 S,S = n * m 。但对于正常情况,处于最短字符串前的字符串依旧要比较所有字符,而不是最短字符串个字符,相对于解法一较差。
空间复杂度:O(1)。
Python
class Solution(object):
def longestCommonPrefix(self, strs):
if len(strs)== 0:
return ""
prefix = strs[0]
for i in range(1,len(strs)):
minLen = min(len(prefix), len(strs[i]))
count=0
for j in range(0,minLen):
if (prefix[j] == strs[i][j]):
count+=1
else:
break
prefix = prefix[0:count]
return prefix
解法三 递归
我们把原来的数组分成两部分,求出左半部分的最长公共前缀,求出右半部分的最长公共前缀,然后求出的两个结果再求最长公共前缀,就是最后的结果了。
求左半部分的最长公共前缀,我们可以继续把它分成两部分,按照上边的思路接着求。然后一直分成两部分,递归下去。
直到该部分只有 1 个字符串,那么最长公共子串就是它本身了,直接返回就可以了。
Java
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
return longestCommonPrefix(strs, 0 , strs.length - 1);
}
//递归不断分成两部分
private String longestCommonPrefix(String[] strs, int l, int r) {
if (l == r) {
return strs[l];
}
else {
int mid = (l + r)/2;
String lcpLeft = longestCommonPrefix(strs, l , mid);
String lcpRight = longestCommonPrefix(strs, mid + 1,r);
return commonPrefix(lcpLeft, lcpRight);
}
}
//求两个结果的最长公共前缀
String commonPrefix(String left,String right) {
int min = Math.min(left.length(), right.length());
for (int i = 0; i < min; i++) {
if ( left.charAt(i) != right.charAt(i) )
return left.substring(0, i);
}
return left.substring(0, min);
}
}