如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
示例 2:
输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
1.自己的方法,注意防止越界
class Solution {
public String longestCommonPrefix(String[] strs) {
int size = strs.length;
if(size == 0) return "";
int len = strs[0].length();
int i ;
for(i = 0; i < len; i++){
char ch = strs[0].charAt(i);
boolean flag = true;
for(int j = 1; j < size; j++){
int len2 = strs[j].length();
if(len2 <= i || strs[j].charAt(i) != ch){
flag = false;
break;
}
}
if(flag == false) break;
}
return strs[0].substring(0, i);
}
}
2.分治法,就归并算法也是用到分治法的思想
也就是先求出左边一般的结果,再求出右边一半的结果,最后二者合并即可
class Solution {
public String longestCommonPrefix(String[] strs) {
int len = strs.length;
if(len == 0) return "";
return find(strs, 0, len - 1);
}
String find(String[] strs, int left, int right){
//if(left > right) return "";
if(left == right) return strs[left];//递推边界
else{
int mid = (left + right)/2;
String leftResu = find(strs, left, mid);
String rightResu = find(strs, mid + 1, right);
return merge(leftResu, rightResu);
}
}
String merge(String s1, String s2){
int len = s1.length();
int len2 = s2.length();
int i;
for(i = 0; i < len; i++){
//if(s2.charAt(i) != s1.charAt(i)) break;
//注意这里要判断是否越界
if(i >= len2 || s2.charAt(i) != s1.charAt(i)) break;
}
return s1.substring(0, i);
}
}
其实递推边界不那样写也是没有关系的
class Solution {
public String longestCommonPrefix(String[] strs) {
int len = strs.length;
if(len == 0) return "";
return find(strs, 0, len - 1);
}
String find(String[] strs, int left, int right){
//if(left > right) return "";
if(left == right) return strs[left];//递推边界
int mid = (left + right)/2;
String leftResu = find(strs, left, mid);
String rightResu = find(strs, mid + 1, right);
return merge(leftResu, rightResu);
}
String merge(String s1, String s2){
int len = s1.length();
int len2 = s2.length();
int i;
for(i = 0; i < len; i++){
//if(s2.charAt(i) != s1.charAt(i)) break;
//注意这里要判断是否越界
if(i >= len2 || s2.charAt(i) != s1.charAt(i)) break;
}
return s1.substring(0, i);
}
}
3.二分查找法
对前缀长度进行二分查找,长度是满足线性关系的
class Solution {
public String longestCommonPrefix(String[] strs) {
int len = strs.length;
if(len == 0) return "";
int min = Integer.MAX_VALUE;
//先确定最短长度,防止越界
for(String st : strs){
min = Math.min(min, st.length());
}
int low = 0, high = min;//注意high取的是当前位的后一位
while(low <= high){
//注意包含等号,相等的时候也需要判断一下
int mid = (low + high)/2;
if(judge(strs, mid)){
//注意如果成立,应当向右增加
low = mid + 1;
}else{
high = mid - 1;
}
}
return strs[0].substring(0, (low + high) / 2);
//注意一下,因为不确定是left,right直接取二者平均值即可
}
boolean judge(String[] strs, int right){
//还是不包含right
int len = strs.length;
String str1 = strs[0].substring(0, right);
for(int i= 1; i < len; i++){
if(!strs[i].startsWith(str1)) return false;
}
return true;
}
}