1. 神仙算法
/**
* @Classname Solution1
* @Description TODO
* @Date 2020/1/11 7:00
* @Author SonnSei
*/
public class Solution1 {
/**
* 神仙算法
* 时间复杂度:O(s),s为所有字符总数
* 空间复杂度:O(1)
* @param strs
* @return
*/
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length == 0)return "";
String prefix = strs[0];
for (int i = 1; i < strs.length; i++) {
while (strs[i].indexOf(prefix) != 0) {
prefix = prefix.substring(0, prefix.length() - 1);
if(prefix.isEmpty()) return "";
}
}
return prefix;
}
}
2. 愚蠢的BF
/**
* @Classname Solution2
* @Description TODO
* @Date 2020/1/12 8:08
* @Author SonnSei
*/
public class Solution2 {
/**
* 愚蠢的暴力
* 时间复杂度:O(s),s为所有字符总数
* 空间复杂度:O(1)
* @param strs
* @return
*/
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
for (int i = 0; i < strs[0].length(); i++) {
for (int j = 1; j < strs.length; j++) {
if (i == strs[j].length() || strs[j].charAt(i) != strs[0].charAt(i))
return strs[0].substring(0, i);
}
}
return strs[0];
}
}
3. 分治
public class Solution3 {
/**
* 感觉这个分治也挺蠢
* 时间复杂度:O(s)
* 空间复杂度O(m*log(n))
* @param strs
* @return
*/
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
return longestCommonPrefix(strs, 0, strs.length - 1);
}
private String longestCommonPrefix(String[] strs, int left, int right) {
if(left==right) return strs[left];
int mid = (left+right)>>>1;
String sl = longestCommonPrefix(strs, left, mid);
String sr = longestCommonPrefix(strs, mid + 1, right);
return commonPrefix(sl, sr);
}
private String commonPrefix(String s1, String s2) {
for (int i = 0; i < Math.min(s1.length(), s2.length()); i++) {
if(s1.charAt(i)!=s2.charAt(i))return s1.substring(0,i);
}
return s1.length()>s2.length()?s2:s1;
}
}
4. 二分查找
public class Solution4 {
/**
* 二分查找
* 时间复杂度:O(S*log(n))
* 空间复杂度:O(1)
* @param strs
* @return
*/
public String longestCommonPrefix4(String[] strs) {
if(strs==null || strs.length == 0)return "";
int minLen = strs[0].length();
for(String item:strs)
minLen = Math.min(minLen, item.length());
int left = 0,right = minLen;
while(left<=right){
int mid = (left+right)>>>1;
if(isCommonPrefix(strs,mid))
left = mid+1;
else
right =mid-1;
}
/*
* 这里为什么要是right?
* 其实一开始是写的Math.min(left,right),但是后来发现直接用right就行
* 假如最后一次left==right之后做判断,
* 如果为true,left右移,但最后结果要取right
* 如果为false,right左移,还是取right
* 有没有考虑right左移变成-1的时候越界?
* 当left==right==0的时候,判定会是true,会left右移,所以right不会越界
*/
return strs[0].substring(0, right);
}
private boolean isCommonPrefix(String[] strs, int len){
String str1 = strs[0].substring(0,len);
for (int i = 1; i < strs.length; i++)
if (!strs[i].startsWith(str1))
return false;
return true;
}
}
来源:CSDN
作者:SonnSei
链接:https://blog.csdn.net/weixin_40602200/article/details/103946676