问题
这个题,leetcode给的信息很少。题目本身是要求一组字符串的相同的前缀(Prefix)。
分析
这个问题,看起来简单,实际上各种边界条件多,坑多。笔者花了一点时间才完全在leetcode上跑通。这次得到的教训有两个:
1. 在解一个算法题时,不要找到一个解法,就不去思考其他的解法了,要尽可能想出多的解法,用笔在纸上列出来,评估一个复杂度低的解法。如果不通,迅速换一个解法,不要钻牛角尖。
1. 在分解一个问题的时,要考虑各种边界条件。例如,字符数组就一个空字符“”,怎么处理,输入字符串就一个字符“a”,如果输入字符串两个字符串“a”,“a”都是a怎么处理?这些边界条件,的确要认真处理。
代码分析
public class Solution {
public String longestCommonPrefix(String[] strs) {
String retStr = "";
//如果输入的字符串数组为空,那么返回空
if (strs.length <= 0)
return "";
//如果输入的字符串数组只有一个字符串,那么就输出这个字符串
if (strs.length == 1)
return strs[0];
//上面两个边界条件处理后,剩下的肯定是多个字符串了
//求解字符串数组中长度最短的字符串
int minLen = strs[0].length();
int idx = 0;
for (int i = 0; i < strs.length; i++) {
if (strs[i].length() < minLen) {
minLen = strs[i].length();
idx = i;
}
}
//算法核心部分,拿两个字符串来比较
//如果每个字符串的同样位子的字符相同,则flag==1
//例如"acd"和"ace"就ac相同,那么把a和c累加到返回字符串上去
int i, j;
int flag = 0;
for (j = 0; j < minLen; j++) {
for (i = 1; i < strs.length; i++) {
if (strs[0].charAt(j) == strs[i].charAt(j) && strs[idx].charAt(j) != '\0') {
flag = 1;
// retStr += ch;
} else {
//flag==0说明字符不相同,就没有遍历的必要了
flag = 0;break;
}
}
if (flag == 1) {
char ch = strs[0].charAt(j);
retStr += ch;
}else{
//flag==0说明字符不相同,就没有遍历的必要了
break;
}
}
return retStr;
}
}
后记
之前采用的算法是,寻找相同prefix的下标j,在通过retStr = strs[0].subString(0,j)来试图解这个题,但是那样,各种边界条件会折磨死人。还不如这个判断一次,累加一次来得实在。如果,你也做错了,没关系,只有不停的试错,才能找出知识的缺陷在哪里。