Leetcode之最長公共前綴

leetcode

原題

在這裏插入圖片描述

我的

我的思路

  1. 默認數組第一位第一個公共前綴
  2. 開始和第二個字符串,比較長度,獲取到兩者短的
  3. for循環兩者短的,從0-最短字符串長度,比較兩者char是否相同,把相同拼接起來,如果不相同,跳出循環
  4. 將拼接的字符串賦值給公共前綴
  5. 如果公共前綴字符串爲”“ return “”
  6. return commonPrefix;

我的代碼實現

    public String longestCommonPrefix(String[] strArray) {
        if (strArray.length < 1) {
            return "";
        }
        if (strArray.length < 2) {
            return strArray[0];
        }
        //默認數組第一位第一個公共前綴
        String commonPrefix = strArray[0];
        for (int i = 1; i < strArray.length; i++) {
            StringBuilder s = new StringBuilder();
            //開始和第二個字符串,比較長度,獲取到兩者短的
            String shortStr = commonPrefix.length() >= strArray[i].length() ? strArray[i] : commonPrefix;
            //for循環兩者短的,從0-最短字符串長度,比較兩者char是否相同,把相同拼接起來,如果不相同,跳出循環
            for (int j = 0; j < shortStr.length(); j++) {
                if (commonPrefix.charAt(j) != strArray[i].charAt(j)) {
                    break;
                }
                s.append(commonPrefix.charAt(j));
            }
            //將拼接的字符串賦值給公共前綴
            commonPrefix = s.toString();
            //如果公共前綴字符串爲”“  return ""
            if ("".equals(commonPrefix)) {
                return commonPrefix;
            }
        }
        return commonPrefix;
    }

leetcode最優

leetcode最優實現的思路

1.賦值第一個字符串爲公共前綴, 實現核心思路通過第二字符串indexOf(公共前綴字符串)!=0
2. 公共前綴長度從後縮短1,再次執行indexOf(),知道!=0,獲取公共前綴長度變成0 indexOf() 肯定!=0
3. return 公共前綴字符串

leetcode 最優實現代碼

     public String smartLongestCommonPrefix(String[] strArray) {
        if (strArray.length == 0) {
            return "";
        }
        //賦值第一個字符串爲公共前綴
        String commonPrefix = strArray[0];
        for (int i = 1; i < strArray.length; i++) {
            // 實現核心思路通過第二字符串indexOf(公共前綴字符串)!=0
            while (strArray[i].indexOf(commonPrefix) != 0) {
                //公共前綴長度從後縮短1,再次執行indexOf(),知道!=0,獲取公共前綴長度變成0 indexOf() 肯定!=0
                commonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1);
            }
            if ("".equals(commonPrefix)) {
                return commonPrefix;
            }
        }
        //return 公共前綴字符串
        return commonPrefix;

    }

總結

別人總結解決方案

大概有這五種思路, 一般都會採用第四種, 但是耗時太多

  1. 所求的最長公共前綴子串一定是每個字符串的前綴子串。所以隨便選擇一個字符串作爲標準,把它的前綴串,與其他所有字符串進行判斷,看是否是它們所有人的前綴子串。這裏的時間性能是O(mnm)。

  2. 列出所有的字符串的前綴子串,將它們合併後排序,找出其中個數爲n且最長的子串。時間性能爲O(nm+mnlog(mn))

  3. 縱向掃描:從下標0開始,判斷每一個字符串的下標0,判斷是否全部相同。直到遇到不全部相同的下標。時間性能爲O(n*m)。

  4. 橫向掃描:前兩個字符串找公共子串,將其結果和第三個字符串找公共子串……直到最後一個串。時間性能爲O(n*m)。

  5. 藉助trie字典樹。將這些字符串存儲到trie樹中。那麼trie樹的第一個分叉口之前的單分支樹的就是所求。

爲什麼最優的比我的快

  1. 我的算法考慮是悲觀情況下,正向的從第一個字符串開始比較,但實際情況沒有這麼悲觀,可能兩個字符串,前一半都是相同的,而我用這種想法去處理的時候導致,我從第一個char到 中間char 都是無效的計算
  2. 最優的算法考慮樂觀的情況,就是大部分情況下,兩個字符串匹配的部分是多的

疑問,請求大佬解惑

  1. 研究下indexOf() 源碼 底層就是KMP算法,理論上時間複雜度是M+N ,最優算法裏面,while重複調用indexOf(),N*(M+N)時間複雜度,憑什麼比我自己寫的for循環 N的時間複雜度快,雖然我有很多無效計算
  2. 這裏用indexOf()肯定是有問題,我覺得最優一個自己寫for循環 從末尾開始考慮,這樣過濾很多無效記錄,而不是用indexOf()
  3. 如果有大佬能解惑,請留言,這裏謝謝了
  4. gitee地址,包含個人對IndexOf() 源碼中文註釋,如果不對地方,求指正:gitee
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章