LeetCodeOJ刷題之14【Longest Common Prefix】

Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.
求字符串數組中字符串的最長公共前綴。git

Solutions

  • 1 Longest Common Prefix -- 11~13ms
    • 第一個映入大腦的是對每個字符串,按字符位逐個比較,直到發現不相同的或者是有個字符串已經比較完了時,說明最大公共前綴已經找到。則時間複雜度是: \(O(MN)\) 其中 M 是字符數組的個數,N 是字符數組中最短字符串的長度。按這種思想的代碼以下:
    class Solution {
    public:
        string longestCommonPrefix(vector<string> &strs) {
            if(strs.size()<=0)return string();
            int idx=0;
            string res;
            char c;
            string s=strs.at(0); //以第一個字串做爲比較的基
            int n=s.size(),ns=strs.size();
            while(idx<n){
                c=strs.at(0).at(idx); //獲取一個字符
                for(int i=0;i<ns;++i){ //循環和其餘字串中對應位的字符進行比較
                    s=strs.at(i);
                    if(idx<s.size())
                        if(s.at(idx)==c)continue;
                    idx=n; //若是出現不相等或有字符串已結束,則退出循環
                    break;
                }
                if(idx<n){
                    res.push_back(c);
                }
                ++idx;
            }
            return res;
        }
    };
    • 分析了一下,這裏佔用時間的有兩個:
      1. 每一次迭代時的字符串拷貝;
      2. 若是最短的字符串在最後一個比較或靠後比較,則就白白浪費了太多比較了,特別是字符串數組很大的時候。
    • 因此對方案 1 進行了改進,有了下面的方案 2 。
  • 2 Longest Common Prefix -- 8ms
    • 這種方案首先找到字串數組中最短的那個,並記錄下其在字符數組中的下標,不進行拷貝,減小空間複雜度,同時,節省一點時間。
    • 其次,去除掉全部的字符串拷貝操做,除用於在大字符串數組狀況下的優化時須要的變量外,儘可能減小空間使用。能夠看到,運行時間一會兒減到了 8ms。說明仍是有效果的。
    • 代碼以下:
    class Solution {
    public:
        string longestCommonPrefix(vector<string> &strs) {
            if(strs.size()<=0)return string();
            int idx=0,base=0;
            string res;
            int ns=strs.size();
            while(idx<ns){
                if(strs.at(idx).size()<strs.at(base).size())
                    base=idx;
                ++idx;
            }
            idx=0;
            char c;
            int n=strs.at(base).size();
            while(idx<n){
                c=strs.at(base).at(idx);
                for(int i=0;i<ns;++i){
                    if(idx<strs.at(i).size())
                        if(strs.at(i).at(idx)==c)continue;
                    idx=n;
                    break;
                }
                if(idx<n){
                    res.push_back(c);
                }
                ++idx;
            }
            return res;
        }
    };
  • 3 Longest Common Prefix -- 8ms
    • 查閱了網友的解答,發現這樣一種思路:
    • 以第一個字串爲比較基的長度斷定,逐位判斷,若是發現有一個字串的長度小於或等於當前位,說明這個字串結束了,天然也應該結束函數;
    • 若是沒有結束,逐位判斷的方式使用:判斷當前字串的當前位和下一個字串的當前位比較是否相同,不相同則結束。能夠看到,效率仍是很高的。
    class Solution {
    public:
        string longestCommonPrefix(vector<string> &strs) {
            if (strs.size() == 0) return "";
            string s;
            for (int i = 0; i < strs[0].length(); i++) {
                for (int j = 0; j < strs.size() - 1; j++) {
                    if (strs[j + 1].length() <= i || strs[j][i] != strs[j + 1][i]) {
                        return s;
                    }
                }
                s.push_back(strs[0][i]);
            }
            return s;
        }
    };
    • 代碼看起來很簡潔,但我認爲,代碼還應該有改進方式,好比應該先遍歷出最短的那個字串,同時,求strs.size()儘可能放到循環外面來,由於其是一個常量,在內層循環中,若是字串數組很大,就會產生必定的沒法消除的效率影響。同時,我更喜歡使用 ++i 代替 i++ ,由於這樣,能減小一次寄存器存取。也許當數據量少時看不出來這些差距,但代碼在手,能優盡優嘛!不過處理了這些,好像就沒原來的好看了~~😄
    • 那麼優化後獲得以下代碼(8ms)
    class Solution {
    public:
        string longestCommonPrefix(vector<string> &strs) {
            if (strs.size() == 0) return "";
            string s;
            int minlen=strs[0].length(),ns=strs.size();
            for(int i=0;i<ns;++i){
                minlen<strs[i].length() ? minlen=strs[i].length() :0 ;
            }
            ns-=1;
            for (int i = 0; i < minlen; ++i) {
                for (int j = 0; j < ns; ++j) {
                    if (strs[j + 1].length() <= i || strs[j][i] != strs[j + 1][i]) {
                        return s;
                    }
                }
                s.push_back(strs[0][i]);
            }
            return s;
        }
    };

附錄

同系列:LeetCodesOJhttp://www.cnblogs.com/lomper/tag/LeetCodesOJ/github

相關文章
相關標籤/搜索