参考资料来自题库:
https://leetcode-cn.com/problems/longest-common-prefix/submissions/
C
#include<cstdio>
#include<string.h>
#include<malloc.h>
//#include<iostream>
//using namespace std;
char * longestCommonPrefix_byDivide(char ** strs,int strsSize){//8ms 7MB
if (strsSize ==0){
return "";
}
char *answer=strs[0];
int i,j;
for (i=1;i<strsSize;i++){
for(j=0;answer[j]!='\0'&&strs[i][j]!='\0';j++){
if(answer[j]!=strs[i][j]){
break;
}
}
answer[j]='\0';
if(answer==NULL){
return "";
}
}
return answer;
}
int main(){
char ** strs=(char **)malloc(sizeof(char*)*3);
int (*p)[20];
for(int i=0;i<3;i++){
strs[i]=(char *)malloc(sizeof(char) *20);
}
for(int i=0;i<3;i++){
scanf("%s",strs[i]);
}
// for(int i=0;i<3;i++){//输出整体字符串数组
// printf("%s\n", *(strs+i) );
// }
int strsSize=3;
char *result=longestCommonPrefix_byDivide(strs, strsSize);
printf("%s\n",(void*)result);
// cout<<result<<endl;//兼容性
for(int i=0;i<3;i++){
free(strs[i]);
}
return 0;
}
c++
#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
//str[0]当作result,一直减少到合适
string longestCommonPrefix(vector <string> &strs)//4ms 11.3MB
{
if (strs.size() == 0) return "";
for (int i = 0; i < strs[0].size(); i++) {//第一列为基准,以它的长度为比较的长度
for (int j = 1; j < strs.size(); j++) {//比较组数
if (strs[j][i] != strs[0][i]) {
return strs[0].substr(0, i);
}
}
}
return strs[0];
}
int main() {
vector<string>strs;
string s;
while (cin >> s) {
strs.push_back(s);
}
cout<<longestCommonPrefix(strs) << endl;
}
java
import java.util.Scanner;
public class TheLongestCommonTest {
//水平扫描法
/*
仍然是先把数组中第一个元素str取出来,然后以这个元素为基准,
使用stringObject.indexOf(searchvalue,fromindex)方法查找,
查一下str是否在strs[i]索引为0的位置,
如果不在索引为0的位置,使用stringObject.substring(start,stop)删减字符串长度,
把str长度减1,再继续查,直到str长度减到0为止。
*/
public static String longestCommonPrefix_byScan(String[] strs){// 1ms 37.9mb
if(strs.length==0) return "";
String result=strs[0];
for (int i=1;i<strs.length;i++){
while(strs[i].indexOf(result)!=0) {//把第一列作为长度标准,一直减少到相同时的长度
result=result.substring(0,result.length()-1);
if(result=="") return "";
}
}
return result;
}
//改良的水平扫描法
/*
不是取数组第一个元素,还是直接取该元素中的单独字符,类似本页中第一种方法,两个for循环,代码稍有区别。
首先第一层for循环(枚举首个字符串的所有字符),使用stringObject.charAt(index)方法获取数组第一个元素的第i个字符,赋值给c,
第二层for循环,从索引1开始遍历数组中所有剩余元素的对应i位置的字符,并与c比较,
如果该字符不等于c,或者压根没有该字符,直接使用stringObject.substring(start,stop)方法返回首个元素从索引0到i的拷贝,
若两层循环都正常运行过,未触发返回,则是类似["ab","abc","abcd"]["aa",aaa"","aaaaa"]这些情况,即第一个元素最短,且整体都符合条件,此时返回这个元素即可。
*/
public static String longestCommonPrefix_byScanPlus(String[] strs){//2ms 37.9MB
if (strs.length==0 ||strs[0].length() ==0){return "";}
for (int i=0,len1=strs[0].length();i<len1;i++){//比较字符个数
char c=strs[0].charAt(i);//获取数组第一个元素的第i个字符,赋值给c
for (int j=1,len2=strs.length;j<len2;j++){//比对组数
if(i== strs[j].length() || strs[j].charAt(i)!=c ){
return strs[0].substring(0,i);
}
}
}
return strs[0];
}
//分治法
/*
把数组拆分成左右两部分,循环拆(递归?),直至最后一层的左右两部分都只有一个元素,
然后将这最后一层的两个元素进行比较,看是否有公共前缀,结果返回上一层,继续比较,最后到顶层;
*/
public static String longestCommonPrefix_byDivide(String []strs){// 1ms
if (strs.length==0 ||strs[0].length() ==0){return "";}
else
return divide(strs,0,strs.length-1);
}//1ms 37.4mb
public static String divide(String []strs,int low,int high){
if(low==high)
return strs[low];
else {
int mid=(low+high)/2;
String leftPre=divide(strs,low,mid);
String rightPre=divide(strs,mid+1,high);
return compare(leftPre,rightPre);
}
}
public static String compare(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);
}
public static void main(String []args){
String []strs=new String[3];
Scanner scanner=new Scanner(System.in);
for (int i=0;i<3;i++){
String s=scanner.next();
strs[i]=String.valueOf(s);
}
System.out.println( longestCommonPrefix_byDivide(strs).toString());
}
}