題目:
給定乙個字串 (s
) 和乙個字元模式 (p
)。實現支援'.'
和'*'
的正規表示式匹配。
'.' 匹配任意單個字元。匹配應該覆蓋整個字串 ('*' 匹配零個或多個前面的元素。
s
) ,而不是部分字串。
說明:示例 1:
輸入:示例 2:s = "aa"
p = "a"
輸出: false
解釋: "a" 無法匹配 "aa" 整個字串。
輸入:示例 3:s = "aa"
p = "a*"
輸出: true
解釋: '*' 代表可匹配零個或多個前面的元素, 即可以匹配 'a' 。因此, 重複 'a' 一次, 字串可變為 "aa"。
輸入:示例 4:s = "ab"
p = ".*"
輸出: true
解釋: ".*" 表示可匹配零個或多個('*')任意字元('.')。
輸入:示例 5:s = "aab"
p = "c*a*b"
輸出: true
解釋: 'c' 可以不被重複, 'a' 可以被重複一次。因此可以匹配字串 "aab"。
輸入:思路:這是乙個經典的動態規劃問題,在面試中經常考到,值得反覆練習~s = "mississippi"
p = "mis*is*p*."
輸出: false
首先確定狀態,
我們定義
dp[i][j]:代表字串s[0~(i-1)]和字串p[0~(j-1)]的匹配狀態,如果dp[i][j]==1,則說明s[0~(i-1)]能被p[0~(j-1)]匹配,反之,當dp[i][j]==0,則說明 s[0~(i-1)]不能被p[0~(j-1)]匹配。
接下來是初始化問題,dp[0][0]代表字串s和字串p都是空串,空串和空串肯定是能匹配的,所以dp[0][0] = 1;當只有字串p是空串時,這時的字串s和字串p肯定是無法匹配的,所以dp[0.....n][0]=0;當只有字串s是空串時,我們看下圖的初始情況,「ab",」a*c*ab",其中「a*」,將會變成乙個空串,所以在dp[0][2] = 1 ,它是由dp[0][0]決定的,這是乙個狀態轉移,即當p[j-1] == '*'時,dp[0][j]=dp[0][j-2]。
最後考慮狀態轉移,
當指標指向的兩個字元相等時,即s[i-1]==p[j-1]或者p[j-1]=='.'(因為'.'可以匹配任意單字元),只有當dp[i-1][j-1]是匹配的,dp[i][j]才是匹配的,如下圖中藍色的位置,狀態轉移方程為 dp[i][j] = dp[i-1][j-1]
2.當指標指向字串p的『*』時,即p[j-1]=='*'時,分兩種情況
①s[i-1]!=p[j-2]&&p[j-2]!='.',也就是「kac","kb*ac",說明此時」b*「應該是乙個空串,當是空串的轉移方程前面提到過,dp[i][j]=dp[i][j-2]
②s[i-1]==p[j-2]||p[j-2]=='.',此時的」*「可以匹配0個,乙個,多個前面的元素
a.當"*"匹配前面0個元素,也就是空串嘍~dp[i][j]=dp[i][j-2]
b.當」*「匹配前面乙個元素時,也就是「a","a*"這種情況,只要字串s」*「前面的匹配了就可以,狀態轉移為dp[i][j]=dp[i][j-1]
c..當」*「匹配前面多個元素時,也就是「aaaa","a*"這種情況,狀態轉移為dp[i][j]=dp[i-1][j]
**:
classsolution
}for(int j=1;j<=m;j++)
else
if(p[j-1]=='*'
) }}
return dp[n][m] != 0
; }
};
LeetCode10 正規表示式
給你乙個字串 s 和乙個字元規律 p,請你來實現乙個支援 和 的正規表示式匹配。匹配任意單個字元 匹配零個或多個前面的那乙個元素 所謂匹配,是要涵蓋 整個 字串 s的,而不是部分字串。說明 s 可能為空,且只包含從 a z 的小寫字母。p 可能為空,且只包含從 a z 的小寫字母,以及字元 和 示例...
LeetCode 10 正規表示式匹配
實現支援 和 的正規表示式匹配。匹配任意單個字元。匹配零個或多個前面的元素。匹配應該覆蓋整個輸入字串 不是部分字串 函式 bool ismatch const char s,const char p 例子 ismatch aa a false ismatch aa aa true ismatch a...
leetCode 10 正規表示式匹配
這道題花了功夫,所以把想到的的寫下來。這個要從字串的屁股開始匹配。道理很簡單,從正面匹配,匹配的方式很多,需要全部列舉,不利於縮小問題規模,舉個例子,aac和a a a c,從正面開始匹配,從全部需要列舉的匹配情況中舉幾個例子 aac匹配a a a c,匹配a a a c,匹配a a a c。從屁股...