LeetCode.28 - 實(shí)現(xiàn)strStr()

題目

實(shí)現(xiàn) strStr() 函數(shù)啸胧。

給定一個(gè) haystack 字符串和一個(gè) needle 字符串迎捺,在 haystack 字符串中找出 needle 字符串出現(xiàn)的第一個(gè)位置 (從0開始)营搅。如果不存在筷转,則返回 -1蔚万。

示例 1:
輸入: haystack = "hello", needle = "ll"
輸出: 2

示例 2:
輸入: haystack = "aaaaa", needle = "bba"
輸出: -1

說明:

當(dāng) needle 是空字符串時(shí),我們應(yīng)當(dāng)返回什么值呢徽曲?這是一個(gè)在面試中很好的問題零截。

對(duì)于本題而言,當(dāng) needle 是空字符串時(shí)我們應(yīng)當(dāng)返回 0 秃臣。這與C語言的 strstr() 以及 Java的 indexOf() 定義相符涧衙。

思路

這個(gè)題乍一看,難度是簡(jiǎn)單奥此?
最熟悉的字符串匹配弧哎,莫過于經(jīng)典的KMP了,理解透徹next數(shù)組怎么說也不能算是簡(jiǎn)單了吧得院?不過很快發(fā)現(xiàn)了簡(jiǎn)單的所在傻铣,可以使用內(nèi)置函數(shù)章贞,這樣一來祥绞,貌似就是一個(gè)優(yōu)雅與否的問題了
不過非洲,抱著這樣的態(tài)度,顯然不太行蜕径,因?yàn)樘岣咦约翰攀俏覀兿胍?br> 看了下大神們的答案两踏,我發(fā)現(xiàn)了BM算法 和 Sunday算法
這里簡(jiǎn)單說下自己對(duì)Sunday算法的理解吧,詳細(xì)的可以戳上面的鏈接看下:

  • 從左往右遍歷對(duì)比

  • 關(guān)注主串中參與匹配的最末位字符后面的那一位(下圖藍(lán)色位置)

  • 兩種情況如圖:


    Case1 & 2
  • 缺點(diǎn)是子串中大量重復(fù)時(shí),效率變差最差O(m*n)

再重復(fù)下兜喻,詳細(xì)請(qǐng)戳鏈接 BM算法 和 Sunday算法

自寫代碼

暴力版

class Solution:
   def strStr(self, haystack: str, needle: str) -> int:
       if len(needle) == 0:
           return 0
       if len(haystack) == 0:
           return -1
       #不用內(nèi)置函數(shù)梦染,直接以needle的長(zhǎng)度依次遍歷
       for i in range(len(haystack)):
           #真的,不要在循環(huán)套循環(huán)了朴皆,你不像個(gè)寫py的
           if haystack[i:i+len(needle)] == needle:
               return i
       return -1

經(jīng)典的KMP算法

    def kmp_search(self, haystack: str, needle: str) -> int:

        def get_next(pattern: str):
            j, k, l = 0, -1, len(pattern)

            p_next = [-1 for _ in range(l)]

            while j < l - 1:
                if k == -1 or pattern[j] == pattern[k]:
                    k += 1
                    j += 1
                    if pattern[j] != pattern[k]:
                        p_next[j] = k
                    else:
                        p_next[j] = p_next[k]
                else:
                    k = p_next[k]

            return p_next

        i, j, h_l, n_l = 0, 0, len(haystack), len(needle)
        p_next = get_next(needle)

        while i < h_l and j < n_l:
            if j == -1 or haystack[i] == needle[j]:
                i += 1
                j += 1
            else:
                j = p_next[j]

        if j == n_l:
            return i - j
        return -1

優(yōu)雅代碼

能兩行不來三行:

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if not needle:return 0
        return haystack.index(needle) if needle in haystack else -1

sunday算法

def sunday_search(self, haystack: str, needle: str) -> int:
        if not needle:
            return 0

        offset = {}
        n_l = len(needle)

        for i in range(n_l):
            offset[needle[i]] = n_l - i

        i, j, h_l = 0, 0, len(haystack)

        while i <= h_l - n_l:
            j = 0

            while haystack[i + j] == needle[j]:
                j += 1
                if j == n_l:
                    return i

            if i + n_l == h_l:
                return -1

            if haystack[i + n_l] in offset:
                i += offset[haystack[i + n_l]]
            else:
                i += n_l + 1

        return -1

自測(cè)反思

  • 當(dāng) needle 是空字符串時(shí)帕识,我們應(yīng)當(dāng)返回什么值呢?
    這句話在題目中給了提示遂铡,而這個(gè)確實(shí)是一個(gè)很好的問題肮疗,邊界,永遠(yuǎn)是測(cè)試重點(diǎn)扒接。
  • 多個(gè)存在伪货,會(huì)不會(huì)出現(xiàn)問題?
  • 不存在钾怔,會(huì)不會(huì)有問題碱呼?

以上,歡迎大家討論宗侦,共同進(jìn)步


歡迎大家關(guān)注我的公眾號(hào)


半畝房頂
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末窗市,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蕾域,更是在濱河造成了極大的恐慌窗悯,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梦皮,死亡現(xiàn)場(chǎng)離奇詭異炭分,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)剑肯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門捧毛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人让网,你說我怎么就攤上這事呀忧。” “怎么了溃睹?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵而账,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我因篇,道長(zhǎng)泞辐,這世上最難降的妖魔是什么笔横? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮咐吼,結(jié)果婚禮上吹缔,老公的妹妹穿的比我還像新娘。我一直安慰自己锯茄,他們只是感情好厢塘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肌幽,像睡著了一般晚碾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喂急,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天迄薄,我揣著相機(jī)與錄音,去河邊找鬼煮岁。 笑死讥蔽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的画机。 我是一名探鬼主播冶伞,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼步氏!你這毒婦竟也來了响禽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤荚醒,失蹤者是張志新(化名)和其女友劉穎芋类,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體界阁,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侯繁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泡躯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贮竟。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖较剃,靈堂內(nèi)的尸體忽然破棺而出咕别,到底是詐尸還是另有隱情,我是刑警寧澤写穴,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布惰拱,位于F島的核電站,受9級(jí)特大地震影響啊送,放射性物質(zhì)發(fā)生泄漏偿短。R本人自食惡果不足惜欣孤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翔冀。 院中可真熱鬧导街,春花似錦披泪、人聲如沸纤子。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽控硼。三九已至,卻和暖如春艾少,著一層夾襖步出監(jiān)牢的瞬間卡乾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工缚够, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留幔妨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓谍椅,卻偏偏與公主長(zhǎng)得像误堡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子雏吭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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