【演算法】LeetCode演算法題-Longest Common Prefix
這是悅樂書的第146次更新,第148篇原創
01 看題和準備
今天介紹的是LeetCode演算法題中Easy級別的第5題(順位題號是14),給定一個隨機的字串陣列,查詢這些字串元素的公共字首字串,如果沒有則返回空串。其中,字串陣列中的元素都是由小寫字母a-z之間隨機組合而成。例如:
輸入:[“flower”,“flow”,“flight”] 輸出:“fl”
輸入: [“dog”,“racecar”,“car”] 輸出: “”
輸入:[“c”] 輸出:“c”
本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。
02 第一種解法
第一步:獲取陣列的第一個元素first。
第二步:擷取first字串的0-1位,判斷陣列從第二個元素到最後一個元素是否都能匹配到擷取的字串,匹配到count就加1,如果count最後的值和陣列除掉第一個元素後的長度相等,則是共有字首。
第三步:如果第二步成功匹配上,則擷取first字串的0-2位,重複第二步的判斷邏輯。
public static String longestCommonPrefix(String[] strs) { String result = ""; if (strs.length == 0) { return ""; } if (strs.length == 1) { return strs[0]; } String first = strs[0]; for (int i=1; i<=first.length(); i++) { String prefix = first.substring(0, i); int count = 0; for (int j=1; j<strs.length; j++) { if (strs[j].indexOf(prefix) == 0) { count = count + 1 ; } } if (count != 0 && count == strs.length-1) { result = prefix; } } return result; }
03 第二種解法
第一步:獲取陣列中第一個元素first。
第二步:用first和陣列第二個元素匹配查詢,找不到就迴圈將first元素從0到倒數第二位擷取,直到first變為空,如果first為空則表示沒有相同的字首。
第三步:用first和陣列第二個元素的共有字首與陣列第三個元素進行匹配查詢,依次往後迴圈。
public static String longestCommonPrefix2(String[] strs) { if (strs.length == 0) { return ""; } String first = strs[0]; for (int i=1; i<strs.length; i++) { while (strs[i].indexOf(first) != 0) { first = first.substring(0, first.length()-1); if (first.isEmpty()) { return ""; } } } return first; }
04 第三種解法
先將原陣列分為兩部分,左邊部分依次獲取共有字首,右邊部分依次獲取共有字首,再將左右兩邊的字首進行查詢,最後得到所有元素共有的字首。此方法有點繞,可以通過除錯或做標記及的方式理解。
public String longestCommonPrefix3(String[] strs) {
if (strs.length == 0) {
return "";
}
return partOf(strs, 0, strs.length-1);
}
public String partOf(String[] strs, int leftIndex, int rightIndex) {
if (leftIndex == rightIndex) {
return strs[leftIndex];
} else {
int midIndex = (leftIndex + rightIndex)/2;
String leftStr = partOf(strs, leftIndex, midIndex);
String rightStr = partOf(strs, midIndex+1, rightIndex);
return getResult(leftStr, rightStr);
}
}
public String getResult (String leftStr, String rightStr) {
int min = Math.min(leftStr.length(), rightStr.length());
for (int i=0; i<min; i++) {
if (leftStr.charAt(i) != rightStr.charAt(i)) {
return leftStr.substring(0, i);
}
}
return leftStr.substring(0, min);
}
05 小結
今天這題要解出來不難,難的是這是否是當前的唯一解?是否還可以另尋他法?
如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!
本文首發於我的個人公眾號:悅樂書,轉載請註明出處!