LeetCode10-正則表示式匹配
今天晚上偶然間看了一期《魯豫有約》,這一期的嘉賓是發哥(不得不說發哥是真的有人格魅力),其中就談到了當時發哥是如何追到發嫂的,發嫂自豪的說:他當時每天給她寫賀卡,堅持了兩年,最終他們在一起了。看到這兒其實感觸挺深的,因為自己總把追女生看作是很乾脆的事情,認識幾天就總想著表白,也總愛胡思亂想,其實是對自己不自信的一種表現,這樣的例子自己沒少犯(看到這兒的讀者請不要笑話我),正如:從前慢,交流只靠書信,但卻真。現在快,但人心太浮躁,給了我很大的啟發了,說到這兒,一個大膽的想法已經在我心中悄悄發芽了。放心,我不會告訴你們的,哈哈哈哈哈。
10 正則表示式匹配
給定一個字串 (s
) 和一個字元模式 (p
'.'
和 '*'
的正則表示式匹配。
'.' 匹配任意單個字元。
'*' 匹配零個或多個前面的元素。
匹配應該覆蓋整個字串 (s
) ,而不是部分字串。
說明:
s
可能為空,且只包含從a-z
的小寫字母。p
可能為空,且只包含從a-z
的小寫字母,以及字元.
和*
。
示例 1:
輸入:
s = "aa"
p = "a"
輸出: false
解釋: "a" 無法匹配 "aa" 整個字串。
示例 2:
輸入:
s = "aa"
p = "a*"
輸出: true
解釋: '*' 代表可匹配零個或多個前面的元素, 即可以匹配 'a' 。因此, 重複 'a' 一次, 字串可變為 "aa"。
示例 3:
輸入:
s = "ab"
p = ".*"
輸出: true
解釋: ".*" 表示可匹配零個或多個('*')任意字元('.')。
示例 4:
輸入:
s = "aab"
p = "c*a*b"
輸出: true
解釋: 'c' 可以不被重複, 'a' 可以被重複一次。因此可以匹配字串 "aab"。
示例 5:
輸入: s = "mississippi" p = "mis*is*p*." 輸出: false
今天發的題目我覺得是挺難的,因為用到了遞迴,遞迴,遞迴!!!困難的事情說三遍。我最煩的就是用遞迴方法了,因為雖然程式碼行數較少,但是其中的邏輯有時候比較難理清,不知道有沒有技術小白有和我這個渣渣一樣的想法。在網上看到了一個不錯的思路
大概思路如下:
- 若p為空,若s也為空,返回true,反之返回false
- 若p的長度為1,若s長度也為1,且相同或是p為'.'則返回true,反之返回false
- 若p的第二個字元不為*,若此時s為空返回false,否則判斷首字元是否匹配,且從各自的第二個字元開始呼叫遞迴函式匹配
- 若p的第二個字元為*,若s不為空且字元匹配,呼叫遞迴函式匹配s和去掉前兩個字元的p,若匹配返回true,否則s去掉首字母
- 返回呼叫遞迴函式匹配s和去掉前兩個字元的p的結果
這一題另外關鍵點就是:分類情況一定要想全,不然就很容易出錯啦
程式碼如下:
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
if p == "":
return s == ""
if len(p) == 1:
return len(s) == 1 and (s[0] == p[0] or p[0] == '.')
if p[1] != "*":
if s == "":
return False
return (s[0] == p[0] or p[0] == '.') and self.isMatch(s[1:], p[1:])
while s and (s[0] == p[0] or p[0] == '.'):
if self.isMatch(s, p[2:]):
return True
s = s[1:]
# 假如第一個字元和匹配規則不匹配,則去判斷之後的是否匹配
return self.isMatch(s, p[2:])
if __name__ == '__main__':
s = "a"
p = "ab"
print(Solution().isMatch(s, p))
執行效率很差,但還是那句話,能跑出來我已經心滿意足了,而且這一題本來就是非常不想做的,滿臉抗拒