zoukankan      html  css  js  c++  java
  • [LeetCode] 44. 通配符匹配

    题目链接 : https://leetcode-cn.com/problems/wildcard-matching/

    题目描述:

    给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?''*' 的通配符匹配。

    '?' 可以匹配任何单个字符。
    '*' 可以匹配任意字符串(包括空字符串)。
    

    两个字符串完全匹配才算匹配成功。

    说明:

    • s 可能为空,且只包含从 a-z 的小写字母。
    • p 可能为空,且只包含从 a-z 的小写字母,以及字符 ?*

    示例:

    示例 1:

    输入:
    s = "aa"
    p = "a"
    输出: false
    解释: "a" 无法匹配 "aa" 整个字符串。
    

    示例 2:

    输入:
    s = "aa"
    p = "*"
    输出: true
    解释: '*' 可以匹配任意字符串。
    

    思路:

    思路一: 利用两个指针进行遍历。

    在代码里解释.

    时间复杂度为:(O(mn))

    思路二:动态规划

    dp[i][j]表示si位置,pj位置是否匹配!

    初始化:

    1. dp[0][0]:什么都没有,所以为true
    2. 第一行dp[0][j],换句话说,s为空,与p匹配,所以只要p开始为*才为true
    3. 第一列dp[i][0],当然全部为False

    动态方程:

    1. 如果(s[i] == p[j] || p[j] == "?") && dp[i-1][j-1] ,有dp[i][j] = true

    2. 如果p[j] == "*" && (dp[i-1][j] = true || dp[i][j-1] = true) dp[i][j] = true

      ​ note:

      dp[i-1][j],表示*代表是空字符,例如ab,ab*

      dp[i][j-1],表示*代表非空任何字符,例如abcd,ab*


    关注我的知乎专栏,了解更多解题技巧,一起进步!

    代码:

    class Solution:
        def isMatch(self, s, p):
            """
            :type s: str
            :type p: str
            :rtype: bool
            """
            i = 0
            j = 0
            start = -1
            match = 0
            while i < len(s):
                # 一对一匹配,匹配成功一起移
                if j < len(p) and (s[i] == p[j] or p[j] == "?"):
                    i += 1
                    j += 1
                # 记录p的"*"的位置,还有s的位置
                elif j < len(p) and p[j] == "*":
                    start = j
                    match = i
                    j += 1
                # j 回到 记录的下一个位置
                # match 更新下一个位置
                # 这不代表用*匹配一个字符
                elif start != -1:
                    j = start + 1
                    match += 1
                    i = match
                else:
                    return False
             # 将多余的 * 直接匹配空串
            return all(x == "*" for x in p[j:])
    

    java

    class Solution {
        public boolean isMatch(String s, String p) {
            int sn = s.length();
            int pn = p.length();
            int i = 0;
            int j = 0;
            int start = -1;
            int match = 0;
            while (i < sn) {
                if (j < pn && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '?')) {
                    i++;
                    j++;
                } else if (j < pn && p.charAt(j) == '*') {
                    start = j;
                    match = i;
                    j++;
                } else if (start != -1) {
                    j = start + 1;
                    match++;
                    i = match;
                } else {
                    return false;
                }
            }
            while (j < pn) {
                if (p.charAt(j) != '*') return false;
                j++;
            }
            return true;
            
        }
    }
    

    思路2

    python

    class Solution:
        def isMatch(self, s, p):
            """
            :type s: str
            :type p: str
            :rtype: bool
            """
            sn = len(s)
            pn = len(p)
            dp = [[False] * (pn + 1) for _ in range(sn + 1)]
            dp[0][0] = True
            for j in range(1, pn + 1):
                if p[j - 1] == "*":
                    dp[0][j] = dp[0][j - 1]
    
            for i in range(1, sn + 1):
                for j in range(1, pn + 1):
                    if (s[i - 1] == p[j - 1] or p[j - 1] == "?"):
                        dp[i][j] = dp[i - 1][j - 1]
                    elif p[j - 1] == "*":
                        dp[i][j] = dp[i - 1][j] or dp[i][j - 1]
            return dp[-1][-1]
    

    java

    class Solution {
        public boolean isMatch(String s, String p) {
            boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
            dp[0][0] = true;
            for (int j = 1; j < p.length() + 1; j++) {
                if (p.charAt(j - 1) == '*') {
                    dp[0][j] = dp[0][j - 1];
                }
            }
            for (int i = 1; i < s.length() + 1; i++) {
                for (int j = 1; j < p.length() + 1; j++) {
                    if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
                        dp[i][j] = dp[i - 1][j - 1];
                    } else if (p.charAt(j - 1) == '*') {
                        dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
                    }
                }
            }
            return dp[s.length()][p.length()];
            
        }
    }
    
  • 相关阅读:
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    how to use automapper in c#, from cf~
  • 原文地址:https://www.cnblogs.com/powercai/p/10863124.html
Copyright © 2011-2022 走看看