leetcode Wildcard Matching
leetcode Wildcard Matching
题目
Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '?' and '*'.
'?' Matches any single character. '*' Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial).
Note:
s could be empty and contains only lowercase letters a-z. p could be empty and contains only lowercase letters a-z, and characters like ? or *. Example 1:
Input: s = "aa" p = "a" Output: false Explanation: "a" does not match the entire string "aa".
大概翻译下,给两个字符串,待匹配串(s)和模式串(p),要求匹配星号和问号。
递归写法
这种方法很好理解,也容易想到,但是对于特别长的串,耗时较长,所以并不能通过所有测试用例。
public boolean isMatch(String s, String p)
{
if (s == null || p == null)
return false;
if (s.equals("") && p.equals(""))
return true;
// 去除多余的* *可以匹配任意, ** 和 * 的作用其实一样,但是会增加程序运行时间
p = processString(p);
return core(0, 0, s, p);
}
private String processString(String s)
{
if (s.equals(""))
return s;
String result = "";
result = result + s.charAt(0);
for (int i = 1; i < s.length(); i++)
{
char temp = s.charAt(i);
if (temp == '*' && s.charAt(i - 1) == '*')
{
continue;
} else
{
result = result + temp;
}
}
return result;
}
//匹配的核心方法,主要在匹配星号那里,星号有三种可能,匹配一个,匹配多个字符,不匹配字符。
private boolean core(int index_s, int index_p, String s, String p)
{
if (index_p == p.length() && index_s == s.length())
return true;
if (index_p >= p.length())
return false;
char pattern = p.charAt(index_p);
if (pattern == '?')
{
return core(index_s + 1, index_p + 1, s, p);
} else if (pattern == '*')
{
return core(index_s, index_p + 1, s, p)
|| (index_s < s.length() && core(index_s + 1, index_p + 1, s, p))
|| (index_s < s.length() && core(index_s + 1, index_p, s, p));
} else
{
if (index_s < s.length() && pattern == s.charAt(index_s))
return core(index_s + 1, index_p + 1, s, p);
else
return false;
}
}
第二种 动态规划
主要理解dp[i][j]代表的意思,意思为:在s串的第i个字符,是否可以匹配到p串第j个字符
public boolean isMatch(String s, String p)
{
if (s == null || p == null)
return false;
int row = s.length();
int col = p.length();
boolean[][] dp = new boolean[row+1][col+1];
dp[0][0] = true;
for (int i = 1; i < dp[0].length; i++)
{
if(p.charAt(i-1)=='*')
dp[0][i] = dp[0][i-1];
}
for (int i = 1; i < dp.length; i++)
{
for (int j = 1; j < dp[0].length; j++)
{
char char_s = s.charAt(i-1);
char char_p = p.charAt(j-1);
if(char_p == '?' || char_p == char_s)
{
dp[i][j] = dp[i-1][j-1];
}else if(char_p == '*')
{
dp[i][j] = dp[i-1][j] || dp[i][j-1];
}else
{
return dp[i][j] = false;
}
}
}
return dp[s.length()][p.length()];
}