97. Interleaving String

問題描述

Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,Given:
s1 = "aabcc",
s2 = "dbbca",
When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.

問題分析

雖然是一道hard題盏缤,但我做的時候思路很明確峻黍,雖然與普通思路好像不太一樣,但效果出奇地好……

  1. 我想的是設(shè)置p1(s1)、p2(s2)间涵、p3(s3)三個指針桩皿,p3每挪一位香缺,與p1坐漏、p2處字母比較,根據(jù)比較結(jié)果進(jìn)行指針移動职员,如果出現(xiàn)兩可的選擇麻蹋,則進(jìn)行遞歸調(diào)用。但如果單純這么做焊切,會超時扮授,因為重復(fù)的枝太多。因此設(shè)置一個記錄不可行狀態(tài)的set专肪,每次出現(xiàn)失敗時刹勃,將(p1, p3)加入狀態(tài)集,根據(jù)這個狀態(tài)集進(jìn)行剪枝嚎尤。
    不過這樣寫出來的代碼很長很難看荔仁,不知道是不是我代碼風(fēng)格還不夠好。
  2. 看了一下九章算術(shù)上的方法,用的是動規(guī)咕晋,代碼比較簡潔。

AC代碼

class Solution(object):
    def isInterleave(self, s1, s2, s3):
        """
        :type s1: str
        :type s2: str
        :type s3: str
        :rtype: bool
        """
        self.record = set([])
        self.n1 = len(s1)
        self.n2 = len(s2)
        self.n3 = len(s3)
        self.s1 = s1
        self.s2 = s2
        self.s3 = s3

        if self.n3 != self.n2 + self.n1:
            return False
        return self.sub(0,0,0)

    def sub(self, p1, p2, p3):
        while p3 < self.n3:
            if p1 == self.n1 or p2 == self.n2:
                break
            if self.s1[p1] == self.s3[p3] and self.s2[p2] == self.s3[p3]:
                f1 = (p1+1, p3+1) in self.record
                f2 = (p1, p3+1) in self.record
                if f1 and f2:
                    self.record.add((p1, p3))
                    return False
                if f1 and not f2:
                    if self.sub(p1, p2+1, p3+1):
                        return True
                    else:
                        self.record.update((p1, p3+1), (p1, p3))
                        return False
                if f2 and not f1:
                    if self.sub(p1+1, p2, p3+1):
                        return True
                    else:
                        self.record.update((p1+1, p3+1), (p1, p3))
                        return False
                else:
                    if self.sub(p1, p2+1, p3+1) or self.sub(p1+1, p2, p3+1):
                        return True
                    else:
                        self.record.add((p1, p3))
                        return False
            elif self.s1[p1] == self.s3[p3] and self.s2[p2] != self.s3[p3]:
                if (p1+1, p3+1) not in self.record:
                    p1 += 1
                    p3 += 1
                else:
                    self.record.update((p1+1, p3+1), (p1, p3))
                    return False
            elif self.s1[p1] != self.s3[p3] and self.s2[p2] == self.s3[p3]:
                if (p1, p3+1) not in self.record:
                    p2 += 1
                    p3 += 1
                else:
                    self.record.update((p1, p3+1), (p1, p3))
                    return False
            else:
                self.record.add((p1, p3))
                return False
        if p1 == self.n1:
            if self.s3[p3:] == self.s2[p2:]:
                return True
            else:
                self.record.add((p1, p3))
                return False
        if p2 == self.n2:
            if self.s3[p3:] == self.s1[p1:]:
                return True
            else:
                self.record.add((p1, p3))
                return False

Runtime: 48 ms, which beats 95.07% of Python submissions.

class Solution(object):
    def isInterleave(self, s1, s2, s3):
        """
        :type s1: str
        :type s2: str
        :type s3: str
        :rtype: bool
        """
        if len(s1) + len(s2) != len(s3):
            return False
        f = [[False for i in range(len(s1) + 1)] for j in range(len(s2) + 1)]
        f[0][0] = True
        for i in range(len(s1)):
            f[0][i+1] = s1[:i+1] == s3[:i+1]
        for i in range(len(s2)):
            f[i+1][0] = s2[:i+1] == s3[:i+1]
        
        for i in range(len(s2)):
            for j in range(len(s1)):
                if s1[j] == s3[i+j+1]:
                    f[i+1][j+1] = f[i+1][j]
                if s2[i] == s3[i+j+1]:
                    f[i+1][j+1] |= f[i][j+1]
        return f[len(s2)][len(s1)]

Runtime: 84 ms, which beats 26.76% of Python submissions.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末收奔,一起剝皮案震驚了整個濱河市掌呜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坪哄,老刑警劉巖质蕉,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異翩肌,居然都是意外死亡模暗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門念祭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兑宇,“玉大人,你說我怎么就攤上這事粱坤×ジ猓” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵站玄,是天一觀的道長枚驻。 經(jīng)常有香客問我,道長株旷,這世上最難降的妖魔是什么再登? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮晾剖,結(jié)果婚禮上锉矢,老公的妹妹穿的比我還像新娘。我一直安慰自己齿尽,他們只是感情好沈撞,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雕什,像睡著了一般缠俺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贷岸,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天壹士,我揣著相機(jī)與錄音,去河邊找鬼偿警。 笑死躏救,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盒使,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼崩掘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了少办?” 一聲冷哼從身側(cè)響起苞慢,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎英妓,沒想到半個月后挽放,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡蔓纠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年辑畦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腿倚。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡纯出,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敷燎,到底是詐尸還是另有隱情潦刃,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布懈叹,位于F島的核電站乖杠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏澄成。R本人自食惡果不足惜胧洒,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望墨状。 院中可真熱鬧卫漫,春花似錦、人聲如沸肾砂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镐确。三九已至包吝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間源葫,已是汗流浹背诗越。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留息堂,地道東北人嚷狞。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓块促,卻偏偏與公主長得像,于是被迫代替她去往敵國和親床未。 傳聞我的和親對象是個殘疾皇子竭翠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

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