1. 程式人生 > >【演算法】LeetCode演算法題-Longest Common Prefix

【演算法】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 小結

今天這題要解出來不難,難的是這是否是當前的唯一解?是否還可以另尋他法?

如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!

本文首發於我的個人公眾號:悅樂書,轉載請註明出處!