https://leetcode.com/articles...
题目
Write a function to find the longest common prefix string amongst an array of strings.
这是一道简单题。但是看了Editorial Solution。感觉自己的算法道路还是很长。
简单的思路
第一种、用第一个字符串去和第二个比,找到公共部分,循环操作和剩下的比。返回公共部分。
第二种、比较每个字符串的第一个字母,全部相同则比较下一个字母。直至出现不同为止。
若数组长度为m,每个字符串长度为n
这两种代码最坏情况花的时间是一致的,都是O(m*n)
个人用了第二种。
代码一
public class Solution {
public String longestCommonPrefix3_2(String[] strs) {
int N = strs.length;
if (N == 0) return "";
// i 一个字符串的长度
// j 数组String[] 长度
// 比较每个字符串的公共部分
String prefix = strs[0];
int i = prefix.length();
for (int j = 0; j < N; j++) {
while (strs[j].indexOf(prefix) != 0) {
prefix = prefix.substring(0, i--);
if (prefix.isEmpty()) return "";
}
}
return prefix;
}
}
Point
s.indexOf(prefix)要考虑prefix是否为""的情况
代码二
public String longestCommonPrefix3(String[] strs) {
int N=strs.length;
if(N==0) return "";
// ith character 一个字符串中 第i个字母
// jth index String[]数组的下标
// 依次比较每个字符串的第i个字母
for(int i=0;i<strs[0].length();i++){
for (int j=1;j<N;j++){
if(i==strs[j].length()||strs[0].charAt(i)!=strs[j].charAt(i))
return strs[0].substring(0,i);
}
}
return strs[0];
}
Point
这个if判断条件现在看来简单精炼,写的时候真是要了命了。主要是边界问题的判断。
首先,位置不能交换。得先判断第i个字母仍在这个字符串的范围内,然后才能根据这个位置i去找这个字母。
其次,位置i得超出边界才能中断返回。不能想着位置i到了边界,就直接返回。因为在这个位置i,其他字符串并没有遍历。因此要等遍历完,i超出边界再中断返回才可以。
二分法
讲真这个最坏情况应该是最慢的,不知道为什么测试结果却比前面两种要快。难道是平均较好?
public String longestCommonPrefix(String[] strs) {
int N = strs.length;
if (N == 0) return "";
int min=Integer.MAX_VALUE;
for(String s:strs)
min=Math.min(min,s.length());
int lo=1;
int hi=min;
while(lo<=hi){
int mid=(lo+hi)/2;
if(isCommonPrefix(strs,mid)){
lo=mid+1;
}
else hi=mid-1;
}
return strs[0].substring(0, (lo+hi)/2);
}
public boolean isCommonPrefix(String[] strs,int len){
int N=strs.length;
String prefix=strs[0].substring(0, len);
for(String s:strs){
if(!s.startsWith(prefix)) return false;
}
return true;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。