1. 程式人生 > >【leetcode】44. (Medium) WildCard Matching

【leetcode】44. (Medium) WildCard Matching

題目連結


解題思路:
這道題的意思就是字串匹配,s是正常的字串,p是帶有特殊字元的字串,在p中,’?‘可以匹配任意一個字元,’*'可以匹配任意長度(包括0)的字元。
這道題可以用DP來做。(初始答案在題目後面的Description裡)

首先動態規劃的特點是會求得所有過程中的結果。
具體做法:
設s=adceb  p=* a* b 我們先建立一個boolean二維陣列match,行數為s.length+1,用於存放s字串;寬為p.length+1,用於存放p字串;
在這裡插入圖片描述
在這裡插入圖片描述陣列中任意一個value的值表示的是當前行及以下的s和當前列及以後的p的字串是否匹配,如果兩個方框所示。所以這裡DP的方法是從尾匹配到頭

現在說明匹配過程:
首先match[s.length][p.length]=true
在這裡插入圖片描述
然後對於最後一排,滿足:

if(p.charAt(i)==’*’)
match[s.length()][i]=true;

就是最後一排,從後到前開始算,遇到p字串的內容是’*'的話,值是true,這裡p字串的後面沒有 ’ * ',所以最後一排的其他數值不做處理,直接跳到倒數第二行。

對於剩下的部分,只對中間部分進行計算,最後一列不做處理:
在這裡插入圖片描述

對於中間部分處理的順序是,從最後一排的尾處理到頭、從倒數第二排的尾處理到頭、…
在這裡插入圖片描述


對於這些內容,處理的規則是:

 if(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')
					  match[i][j]=match[i+1][j+1];
				  else if(p.charAt(j)=='*')
					  match[i][j]=match[i+1][j]||match[i][j+1];
				  else
					  match[i][j]=false;

即分為三種情況,第一種:s[i]和p[j]字元是相同的
此時3處的數值match[i][j]取決於右下方的數值match[i+1][j+1]:
在這裡插入圖片描述

第二種,p[j]==’*’:
此時只要match[i][j]的右邊是true或者下邊是true,自己就是true:
在這裡插入圖片描述

第三種情況,s[i]!=p[j]:
直接false
在這裡插入圖片描述

根據這個規則可以填滿所有的地方:

* a * b -
a true true true false
d false false true false
c false false true false
e false false true false
b false false true true
- true

同時,match[0][0]就是最終的答案:
在這裡插入圖片描述
這個過程其實將所有過程中的答案都給了出來,符合DP的特點,比如下圖中:
在這裡插入圖片描述

這個值的意思是" c e b “和” * b "字串是匹配的

在這裡插入圖片描述
這個值表示"dceb"和"* a* b"是不匹配的


提交程式碼:

class Solution{
	  public boolean isMatch(String s, String p) {
		  boolean match[][]=new boolean[s.length()+1][p.length()+1];
		  match[s.length()][p.length()]=true;
		  
		  for(int i=p.length()-1;i>=0;i--) {
			  if(p.charAt(i)=='*')
				  match[s.length()][i]=true;
			  else break;
		  }
		  
		  for(int i=s.length()-1;i>=0;i--) {
			  for(int j=p.length()-1;j>=0;j--) {
				  if(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')
					  match[i][j]=match[i+1][j+1];
				  else if(p.charAt(j)=='*')
					  match[i][j]=match[i+1][j]||match[i][j+1];
				  else
					  match[i][j]=false;
			  }
		  }
		  
		  return match[0][0];
	  }
}

執行結果:
在這裡插入圖片描述