这个题目是一个easy,但是我觉得并不easy,因为边界条件真的是太多太多太多太多了。多的我都不想做了。但是还是要硬着头皮分析一下会有哪些边界。
- 是个空数组的情况,那么也是直接返回“”;
- 数组中只有一个单词的情况,那么直接返回这个单词就行了。
- 数组中只要有任何一个单词的长度为0(即为“”),那么可以直接返回“”;
- 只要涉及到数组下标的变量都要保证这个下标是不能越界的。
直接上代码:
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0) //空数组直接返回
return "";
if (strs.length == 1) //数组只有一个字符串,直接返回这个字符串
return strs[0];
int result = Integer.MAX_VALUE; //以数组中第一个为标准,记住共同前缀的下标
for (int i = 1; i < strs.length; ++i) {
int j = 0;
if (strs[i].length() == 0) //只要有一个字符串为空,则直接返回""
return "";
//此处一定要保证j不能越界,对于两个字符串均是不能越界
for (j = 0; j < strs[i].length() && j < strs[0].length() && strs[i].charAt(j)==strs[0].charAt(j); ++j);
if (j == 0) result = 0; //说明没有公共前缀
if (j > 0 && j < result) //否则记住这个下标(其实是指向的第一个不相同的元素,但在后面substring就可以把此元素去掉)
result = j;
}
return strs[0].substring(0, result);
}
最后看一下被边界条件坑死的战绩(其实不能算坑,只是自己没有仔细考虑这些)
2020.3.17来更新了,上面的那个解答怎么说呢,考虑的很多,但是很不优雅。下面就看一个刚刚写的归并判断的方法,其实就是归并排序的思想,递归判断:
- 如果是一个字符串,直接返回
- 如果是两个字符串,返回两者的公共前缀
就这样递归判断即可,代码如下:
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length == 0)
return "";
return helper(strs, 0, strs.length-1);
}
private String helper(String[] strs, int start, int end) {
if(start == end) //只有一个字符串,直接返回
return strs[start];
if(start == end-1) //两个字符串,返回两者公共前缀
return longest2Prefix(strs[start], strs[end]);
int mid = start+(end-start)/2;
String left = helper(strs, start, mid); //得到左半边的公共前缀
String right = helper(strs, mid+1, end); //得到右半边的公共前缀
return longest2Prefix(left, right); //得到左右两者共同的公共前缀
}
//得到两个字符串的公共前缀
private String longest2Prefix(String s1, String s2) {
int l1 = 0, l2 = 0;
while(l1 < s1.length() && l2 < s2.length() && s1.charAt(l1) == s2.charAt(l2)) {
l1++;
l2++;
}
return s1.substring(0, Math.min(l1, l2));
}
}