复杂度 字符串平均长度m,数目n
单对这个题来说,最核心的就是拿到两个字符串的公共前缀,下面是方法
复杂度 m
public static String conquer(String s1,String s2) {
int i;
int min = Math.min(s1.length(),s2.length());
for ( i = 0; i < min; i++) {
if(s1.charAt(i)!=s2.charAt(i)){
break;
}
}
return s1.substring(0,i);
}
第一个念头就是暴力 m*n
public static String longestCommonPrefix1(String[] strs) {
String res = strs[0];
int len = strs.length;
for (int i = 0; i < len; i++) {
String str = strs[i];
res = conquer(str,res);
}
return res;
}
然后题解中看到一个很好的思路,通过对字符串进行排序,first 和 last一定前缀相差数最多,只要拿到这两个的公共前缀,就可以了。
复杂度和排序相关
public static String longestCommonPrefix2 (String[]strs){
if (strs.length == 0) return "";
Arrays.sort(strs);
String first = strs[0];
String last = strs[strs.length - 1];
return conquer(last,first);
}
分治也是题解看到的,这个题分治不是最优解 m*n
排序return是在s>e时,这样它能在上一层拿到s,e从而取到值,这个题是在分到只有一个元素时时返回这个值。
感觉一个题只有适用于结合律,它才可以归并。例如
min(a,b,c) = min(min(a,b),c);
// 分治,递归
public static String longestCommonPrefix3 (String[]strs){
return divide(strs, 0, strs.length - 1);
}
//分
public static String divide (String[]strs,int s, int e){
if (s == e) return strs[s];
int mid = (s + e) / 2;
String s1 = divide(strs, s, mid);
String s2 = divide(strs, mid + 1, e);
return conquer(s1, s2);
}
//治
public static String conquer (String s1, String s2){
int i;
int min = Math.min(s1.length(), s2.length());
for (i = 0; i < min; i++) {
if (s1.charAt(i) != s2.charAt(i)) {
break;
}
}
return s1.substring(0, i);
}