File tree Expand file tree Collapse file tree 3 files changed +84
-26
lines changed 
solution/0000-0099/0010.Regular Expression Matching Expand file tree Collapse file tree 3 files changed +84
-26
lines changed Original file line number Diff line number Diff line change 5454
5555## 解法  
5656
57- 动态规划法,` dp[i][j] `  表示 s 的前 i 项和 p 的前 j 项是否匹配。
57+ ** 方法一:动态规划** 
58+ 
59+ 定义 ` dp[i][j] `  表示 s 的前 i 项和 p 的前 j 项是否匹配。
5860
5961现在如果已知了 ` dp[i-1][j-1] `  的状态,我们该如何确定 ` dp[i][j] `  的状态呢?我们可以分三种情况讨论,其中,前两种情况考虑了所有能匹配的情况,剩下的就是不能匹配的情况了:
6062
6466    -  ` p[j-1] == s[i] `  or ` p[j-1] == '.' ` :` * `  前面的字符可以与 s[ i]  匹配,这种情况下,` * `  可能匹配了前面的字符的 0 个,也可能匹配了前面字符的多个,当匹配 0 个时,如 ` ab `  和 ` abb* ` ,或者 ` ab `  和 ` ab.* `  ,这时我们需要去掉 p 中的 ` b* `  或 ` .* `  后进行比较,即 ` dp[i][j] = dp[i][j-2] ` ;当匹配多个时,如 ` abbb `  和 ` ab* ` ,或者 ` abbb `  和 ` a.* ` ,我们需要将 s[ i]  前面的与 p 重新比较,即 ` dp[i][j] = dp[i-1][j] ` 。
65673 .  其他情况:以上两种情况把能匹配的都考虑全面了,所以其他情况为不匹配,即 ` dp[i][j] = False ` 。
6668
69+ 设 s 的长度为 m,p 的长度为 n,则时间复杂度为 $O(m \times n)$,空间复杂度为 $O(m \times n)$。
70+ 
71+ ** 方法二:递归** 
72+ 
73+ 方法一的递归形式实现,相比于方法一,代码更容易理解。
74+ 
75+ 设 s 的长度为 m,p 的长度为 n,则时间复杂度为 $O(m \times n)$,由于是尾递归,故空间复杂度为 $O(1)$。
76+ 
6777<!--  tabs:start --> 
6878
6979### ** Python3**  
@@ -160,6 +170,8 @@ public:
160170
161171### **Go** 
162172
173+ 动态规划非递归实现: 
174+ 
163175```go 
164176func isMatch(s string, p string) bool { 
165177	m, n := len(s), len(p) 
@@ -193,6 +205,34 @@ func isMatch(s string, p string) bool {
193205} 
194206``` 
195207
208+ 动态规划递归实现:
209+ 
210+ ``` go 
211+ func  isMatch (s  string , p  string ) bool  {
212+ 	var  dp  func (x, y int ) bool 
213+ 	dp = func (x, y int ) bool  {
214+ 		if  y == len (p) {
215+ 			return  x == len (s)
216+ 		}
217+ 
218+ 		//  匹配
219+ 		if  x < len (s) && (s[x] == p[y] || p[y] == ' .'  ) {
220+ 			//  下一个为 '*'
221+ 			if  y+1  < len (p) && p[y+1 ] == ' *'   {
222+ 				return  dp (x, y+2 ) || dp (x+1 , y)
223+ 			}
224+ 			return  dp (x+1 , y+1 )
225+ 		}
226+ 		//  不匹配但下一个元素为 '*'
227+ 		if  y+1  < len (p) && p[y+1 ] == ' *'   {
228+ 			return  dp (x, y+2 )
229+ 		}
230+ 		return  false 
231+ 	}
232+ 	return  dp (0 , 0 )
233+ }
234+ ``` 
235+ 
196236### ** JavaScript**  
197237
198238``` js 
Original file line number Diff line number Diff line change @@ -180,6 +180,31 @@ func isMatch(s string, p string) bool {
180180} 
181181``` 
182182
183+ ``` go 
184+ func  isMatch (s  string , p  string ) bool  {
185+ 	var  dp  func (x, y int ) bool 
186+ 	dp = func (x, y int ) bool  {
187+ 		if  y == len (p) {
188+ 			return  x == len (s)
189+ 		}
190+ 
191+ 		if  x < len (s) && (s[x] == p[y] || p[y] == ' .'  ) {
192+ 			//  下一个为 '*'
193+ 			if  y+1  < len (p) && p[y+1 ] == ' *'   {
194+ 				return  dp (x, y+2 ) || dp (x+1 , y)
195+ 			}
196+ 			return  dp (x+1 , y+1 )
197+ 		}
198+ 
199+ 		if  y+1  < len (p) && p[y+1 ] == ' *'   {
200+ 			return  dp (x, y+2 )
201+ 		}
202+ 		return  false 
203+ 	}
204+ 	return  dp (0 , 0 )
205+ }
206+ ``` 
207+ 
183208### ** JavaScript**  
184209
185210``` js 
Original file line number Diff line number Diff line change 11func  isMatch (s  string , p  string ) bool  {
2- 	m , n  :=  len (s ), len (p )
3- 	if  n  ==  0  {
4- 		return  m  ==  0 
5- 	}
6- 	dp  :=  make ([][]bool , m + 1 )
7- 	for  i  :=  0 ; i  <  m + 1 ; i ++  {
8- 		dp [i ] =  make ([]bool , n + 1 )
9- 	}
10- 	dp [0 ][0 ] =  true 
11- 	for  j  :=  1 ; j  <  n + 1 ; j ++  {
12- 		if  p [j - 1 ] ==  '*'  {
13- 			dp [0 ][j ] =  dp [0 ][j - 2 ]
2+ 	var  dp  func (x , y  int ) bool 
3+ 	dp  =  func (x , y  int ) bool  {
4+ 		if  y  ==  len (p ) {
5+ 			return  x  ==  len (s )
146		}
15- 	}
16- 	for  i  :=  1 ; i  <  m + 1 ; i ++  {
17- 		for  j  :=  1 ; j  <  n + 1 ; j ++  {
18- 			if  s [i - 1 ] ==  p [j - 1 ] ||  p [j - 1 ] ==  '.'  {
19- 				dp [i ][j ] =  dp [i - 1 ][j - 1 ]
20- 			} else  if  p [j - 1 ] ==  '*'  {
21- 				if  s [i - 1 ] ==  p [j - 2 ] ||  p [j - 2 ] ==  '.'  {
22- 					dp [i ][j ] =  dp [i ][j - 2 ] ||  dp [i - 1 ][j ]
23- 				} else  {
24- 					dp [i ][j ] =  dp [i ][j - 2 ]
25- 				}
7+ 
8+ 		// 匹配 
9+ 		if  x  <  len (s ) &&  (s [x ] ==  p [y ] ||  p [y ] ==  '.' ) {
10+ 			// 下一个为 '*' 
11+ 			if  y + 1  <  len (p ) &&  p [y + 1 ] ==  '*'  {
12+ 				return  dp (x , y + 2 ) ||  dp (x + 1 , y )
2613			}
14+ 			return  dp (x + 1 , y + 1 )
15+ 		}
16+ 		// 不匹配但下一个元素为 '*' 
17+ 		if  y + 1  <  len (p ) &&  p [y + 1 ] ==  '*'  {
18+ 			return  dp (x , y + 2 )
2719		}
20+ 		return  false 
2821	}
29- 	return  dp [ m ][ n ] 
30- }
22+ 	return  dp ( 0 ,  0 ) 
23+ }
    
 
   
 
     
   
   
          
     
  
    
     
 
    
      
     
 
     
    You can’t perform that action at this time.
  
 
    
  
     
    
      
        
     
 
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments