歸併的解法
題目:編寫一個函數來查找字符串數組中的最長公共前綴。
如果不存在公共前綴,返回空字符串 “”。
示例 1:
輸入: [“flower”,”flow”,”flight”]
輸出: “fl”
示例 2:
輸入: [“dog”,”racecar”,”car”]
輸出: “”
解釋: 輸入不存在公共前綴。
說明:
所有輸入只包含小寫字母 a-z 。
在網上看到好多人的做法其實還是暴力解法,這個題可以用歸併的方法來解決,歸併的一般用途是排序,即歸併排序,在這裏用來解這道題是最合適不過了,主要思想就是,先劃分,再歸併,這樣首先求出2個字符串元素的最長公共前綴,然後再求出4個元素的最長公共前綴,以此類推。但是每一次歸併僅僅還是針對兩個已經求出的最長公共前綴來做歸併的,避免了對整個字符串元素進行遍歷,而且最長公共元素是越來越短,時間效率上也就是越來越快,那麼下面附上代碼供大家參考:
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
return mergeCommonPrefix(strs, 0, strs.length - 1);
}
public String merge(String s1, String s2) {
if (s1 == null || s2 == null || s1 == "" || s2 == "") return "";
StringBuffer sb = new StringBuffer();
int i = 0;
int index = Math.min(s1.length() - 1, s2.length() - 1);
while (i <= index) {
if (s1.charAt(i) == s2.charAt(i)) sb.append(s1.charAt(i++));
else return sb.toString();
}
return sb.toString();
}
public String mergeCommonPrefix(String[] a, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;// 劃分子序列
String s1 = mergeCommonPrefix(a, start, mid);// 對左側子序列進行遞歸合併
String s2 = mergeCommonPrefix(a, mid + 1, end);// 對右側子序列進行遞歸合併
return merge(s1, s2);// 合併兩個最長公共前綴
} else {// 當子序列中只有一個元素時結束遞歸
return a[start];
}
}
}
雖然看起來我的代碼很長,但是核心代碼就是那個merge()函數,是不是很短。歸併的時間複雜度:O(n log n),但是我認爲要比這個複雜度還要低,因爲最長公共前綴一定是在不斷縮短或不變。