题目
给你一个输入字符串 (s) 和一个字符模式 § ,请你实现一个支持 ‘?’ 和 ‘’ 匹配规则的通配符匹配:
‘?’ 可以匹配任何单个字符。
'’ 可以匹配任意字符序列(包括空字符序列)。
判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。
示例 1:
输入:s = “aa”, p = “a”
输出:false
解释:“a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:s = “aa”, p = ""
输出:true
解释:'’ 可以匹配任意字符串。
示例 3:
输入:s = “cb”, p = “?a”
输出:false
解释:‘?’ 可以匹配 ‘c’, 但第二个 ‘a’ 无法匹配 ‘b’。
提示:
0 <= s.length, p.length <= 2000
s 仅由小写英文字母组成
p 仅由小写英文字母、‘?’ 或 ‘*’ 组成
思路
这个问题可以使用动态规划来解决,其中 dp[i][j]
表示字符串 s
的前 i
个字符和模式 p
的前 j
个字符是否匹配。
解题思路如下:
-
初始化动态规划表
dp
,大小为(len(s) + 1) x (len(p) + 1)
。 -
初始化
dp[0][0]
为True
,表示空字符串与空模式匹配。 -
对于模式
p
中的*
,因为*
可以匹配任意字符序列(包括空字符序列),所以可以将dp[0][j]
设置为dp[0][j - 1]
,即模式中的*
可以匹配空字符串。 -
开始动态规划过程,遍历
dp
表格,其中dp[i][j]
的计算取决于以下情况:- 如果
s[i - 1]
和p[j - 1]
相等,或者p[j - 1]
是?
,则dp[i][j] = dp[i - 1][j - 1]
。 - 如果
p[j - 1]
是*
,则dp[i][j] = dp[i - 1][j] || dp[i][j - 1]
。这表示*
可以匹配多个字符或者空字符串。
- 如果
-
最终,
dp[len(s)][len(p)]
的值就表示整个字符串s
是否与模式p
完全匹配。文章来源:https://www.toymoban.com/news/detail-660640.html
这个算法的时间复杂度是 O(m * n),其中 m
是字符串 s
的长度,n
是模式 p
的长度。文章来源地址https://www.toymoban.com/news/detail-660640.html
代码
object Solution {
def isMatch(s: String, p: String): Boolean = {
val m = s.length
val n = p.length
val dp = Array.ofDim[Boolean](m + 1, n + 1)
dp(0)(0) = true
for (j <- 1 to n) {
if (p(j - 1) == '*') {
dp(0)(j) = dp(0)(j - 1)
}
}
for (i <- 1 to m) {
for (j <- 1 to n) {
if (s(i - 1) == p(j - 1) || p(j - 1) == '?') {
dp(i)(j) = dp(i - 1)(j - 1)
} else if (p(j - 1) == '*') {
dp(i)(j) = dp(i - 1)(j) || dp(i)(j - 1)
}
}
}
dp(m)(n)
}
def main(args: Array[String]): Unit = {
val s1 = "aa"
val p1 = "a"
println(isMatch(s1, p1)) // 输出 false
val s2 = "aa"
val p2 = "*"
println(isMatch(s2, p2)) // 输出 true
val s3 = "cb"
val p3 = "?a"
println(isMatch(s3, p3)) // 输出 false
}
}
到了这里,关于leetcode-动态规划-44-通配符匹配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!