No.0011-CareerCup

Given a list of string that represent class names in CamelCaseNotation and a pattern. Write a function that returns the matching elements as a list. Example:
List:['HelloMars','HelloWorld','HelloWorldMars','HiHo']
input: 'H'->output:['HelloMars','HelloWorld','HelloWorldMars','HiHo'];
input: 'HW'->output:['HelloWorld','HelloWorldMars'];
input:'Ho'->output:[];
input:'HeWorM'->output:['HelloWorldMars'].
給出一組符合“駝峰命名規(guī)則”的字符串和一個(gè)字符模板,返回一個(gè)包含所有符合這個(gè)模板的字符串的數(shù)組。至于怎樣才算符合模板,請(qǐng)看上面的例子。

1. 詢(xún)問(wèn)

字符是不是都是大小寫(xiě)?假設(shè)是。
對(duì)空的模板如何處理?假設(shè)返回None。
輸入是不是合法的?比如模板會(huì)不會(huì)有小寫(xiě)字母開(kāi)頭的情況?假設(shè)沒(méi)有,并且輸入都是合法的。

2. 分析

規(guī)律分析

這道題沒(méi)有明顯的暴力破解,而只要摸到規(guī)律,離解題其實(shí)也不遠(yuǎn)了。
假設(shè)字符都是大小寫(xiě)字母,那么可以把一個(gè)字符串看做由大寫(xiě)字母分割的一個(gè)字符串組,例如'HelloWorldMars'可以分割成為['Hello','World','Mars']。同樣模板也可以這么分割。很明顯,模板分割后的數(shù)組長(zhǎng)度應(yīng)該小于等于字符串組的長(zhǎng)度,而且在其長(zhǎng)度范圍內(nèi),每一個(gè)元素都應(yīng)該是字符串組的子串(這里認(rèn)為相等也是子串的一種情況)。
對(duì)字符串進(jìn)行如上描述的分割,復(fù)雜度應(yīng)該是O(N),N為字符串長(zhǎng)度,因?yàn)橐闅v整個(gè)字符串。假設(shè)給出的數(shù)組里面有k個(gè)字符串,那么都進(jìn)行分割也就是k個(gè)O(Li)求和等于O(L),L為長(zhǎng)度之和。然后都和模板比較,生成模板的復(fù)雜度是O(H)假設(shè)模板長(zhǎng)度為H,每次比較的復(fù)雜度為O(min(H, Li)),總體時(shí)間復(fù)雜度是比較復(fù)雜的一個(gè)東西。

優(yōu)化

上面有一個(gè)很明顯的浪費(fèi):假設(shè)模板字符串分解后長(zhǎng)度為3,那么有必要對(duì)長(zhǎng)度為999的字符串進(jìn)行徹底分解嗎?答案是沒(méi)有必要。分解出兩個(gè)以后,就可以使用其進(jìn)行比較了。例如模板為ABC,字符串為ABCDEFG……,分解到[A,B,CDEFG……]即可。
那么,假如這個(gè)字符串分解后長(zhǎng)度還是3,但是中間夾雜很多不需要的東西怎么辦?模板為ABC,字符串大寫(xiě)字母也都是ABC,但是中間插了幾萬(wàn)個(gè)小寫(xiě)字母?對(duì)于這個(gè)問(wèn)題,我認(rèn)為是沒(méi)法優(yōu)化的,因?yàn)槟切┬?xiě)字母都得看,萬(wàn)一不看冒出一個(gè)大寫(xiě)字母來(lái),結(jié)果就錯(cuò)了。
在這一步,可以看到效率肯定提高了,但是復(fù)雜度不變,因?yàn)榭紤]的是最壞情況,還是整個(gè)字符串都得看。
然后比較。假如字符串結(jié)果的長(zhǎng)度小于模板結(jié)果長(zhǎng)度,沒(méi)有必要比較,直接fail。然后通過(guò)上面那一步,保證長(zhǎng)度都是一樣的,也就是說(shuō)是O(H)。同樣,這個(gè)也沒(méi)得優(yōu)化,必須按照模板一個(gè)個(gè)比較下去,否則萬(wàn)一里面有一個(gè)不一樣,結(jié)果是否。
因此,最后的時(shí)間復(fù)雜度為O(kH+L),空間復(fù)雜度是O(H+L)。

發(fā)散

上面的解法用了額外空間,有沒(méi)有可能不需要額外空間,直接拿出兩個(gè)字符串比較?
如果是那樣,可能要用到雙指針,一個(gè)指向模板,一個(gè)指向字符串,本質(zhì)上邏輯和分組的方法一樣,先比較完模板里面的一組,然后移動(dòng)指針到下一組開(kāi)始的地方繼續(xù)比較。因?yàn)榍闆r很多,最壞情況下時(shí)間復(fù)雜度是O(H+Li),k次也就是O(kH+L)。這種方法總體而言空間效率更好。當(dāng)然,代碼更難寫(xiě)。前面那個(gè)解法,就是按照大寫(xiě)字母分組稍微麻煩一些,之后都是很簡(jiǎn)單的編程。
不過(guò)既然有更好的解法,就寫(xiě)這個(gè)吧。

3. 代碼

class Solution:
    def stringPattern(self, p, list):
        if not p or not list:
            return None
        res = []
        for s in list:
            if self.isMatch(p, s):
                res.append(s)
        return res

    def isMatch(self, p, s):
        if not s:
            return False
        p1 = p2 = 0
        while p1 < len(p) and p2 < len(s):
            # compare first upper char
            if p[p1] != s[p2]:
                return False
            else:
                p1 += 1
                p2 += 1
            # compare rest lower char
            while p1 < len(p) and p2 < len(s):
                # if found next upper char, break
                if 'A' <= p[p1] <= 'Z':
                    break
                else:
                    if p[p1] != s[p2]:
                        return False
                    else:
                        p1 += 1
                        p2 += 1
            # s skip until next upper char
            while p2 < len(s) and not 'A' <= s[p2] <= 'Z':
                p2 += 1
        if p1 == len(p):
            return True
        else:
            return False

4. 總結(jié)

難度medium。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 第5章 引用類(lèi)型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類(lèi)型 使用基本類(lèi)型...
    大學(xué)一百閱讀 3,270評(píng)論 0 4
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,991評(píng)論 19 139
  • UIViewController和UIView Controller顧名思義,主要是用來(lái)做控制的,View是用來(lái)做...
    bigParis閱讀 370評(píng)論 0 1
  • 愿你的圣誕節(jié)永遠(yuǎn)快樂(lè)美好 時(shí)間:2015年12月25日 地點(diǎn):北京,XX醫(yī)院 6點(diǎn),醫(yī)院已經(jīng)開(kāi)始忙碌了起來(lái),護(hù)士到...
    圓豆閱讀 880評(píng)論 2 2
  • 廈門(mén)人相當(dāng)長(zhǎng)情,我們總?cè)滩蛔∫匚哆^(guò)去 小時(shí)候 中山公園里有個(gè)老頭捏泥人特別逼真 文化宮地下廣場(chǎng)打子彈機(jī)可以贏糖吃...
    萌達(dá)眾籌閱讀 356評(píng)論 0 1