美文网首页
LeetCode刷题笔记5:通配符匹配

LeetCode刷题笔记5:通配符匹配

作者: 蜗流爬树 | 来源:发表于2020-07-06 09:43 被阅读0次

    题目描述

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

    '?' 可以匹配任何单个字符。 '*' 可以匹配任意字符串(包括空字符串)。 两个字符串完全匹配才算匹配成功。

    示例

    来自LeetCode
    来自LeetCode
    题目链接

    动态规划

    可以使用dp[i][j]来保存s的前i个字符与p的前j个字符匹配情况。当p取到‘?’或者两个字符串取出来的字符相同时。只需要看dp[i-1][j-1]的情况即可,也就是之前的字符串匹配情况。if(p[j]==s[i] || p[j]=='?') dp[i][j]=dp[i-1][j-1]
    若p取出来的是‘’时,我们需要考虑两种情况,匹配一个空串时,则当s的前i个字符与p的前j-1个字符匹配成功则认为匹配成功。另一种情况则是*匹配s[i],此时若s的前i-1个字符与p的前j个字符匹配成功则认为匹配成功。即if(p[j]=='*')dp[i][j]=dp[i-1][j] || dp[i][j-1].
    注意,当*匹配是s[i]时,dp[i][j]=dp[i-1][j]而不是dp[i-1][j-1]因为匹配一个字符后,*仍然可以继续匹配其他字符或空串,若写成dp[i][j]=dp[i-1][j-1]则意味着抛弃了这个*,它不继续匹配。如s="abc" ,p="a*" *匹配c后我们查看“ab”与“a*”的匹配情况,而不是跳过*直接查看“ab”与"a"的匹配情况。
    我们还需要注意边界情况,空串与空串是可以匹配成功的,所以dp[0][0]=true.若p取空串,则dp[i][0]=false(i>0).若s为空则只有当p[0:j]为'*'时dp[0][j]=ture 否则为false。

     //dp[i][j]保存s的前i个字符与p的前j个字符匹配情况。
            boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
            dp[0][0] = true;
            for (int i = 0; i < p.length(); i++) {//当p的前i个字符均为*时,才能匹配s为空的情况
                if (p.charAt(i) == '*')
                    dp[0][i + 1] = true;
                else break;
            }
            for (int i = 1; i <= s.length(); i++) {
                for (int j = 1; j <= p.length(); j++) {
                    if (p.charAt(j - 1) == '*') {//*匹配空串或s的一个字符
                        dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
                    } else if (p.charAt(j - 1) == '?' || p.charAt(j - 1) == s.charAt(i - 1)) {//单个字符匹配
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                }
            }
            return dp[s.length()][p.length()];
    

    动态规划可以通过测试,但效率并不算高。


    效率并不理想

    据说这题用贪心算法的效率会比动态规划高,有时间研究一下

    相关文章

      网友评论

          本文标题:LeetCode刷题笔记5:通配符匹配

          本文链接:https://www.haomeiwen.com/subject/smybqktx.html