Leetcode每日一题专题

通配符匹配

字符串、动态规划

思路:

动态规划法:

1.定义数组dp[i][j]:s的前i个字符串匹配p的前j个字符串

2.数组之间的关系:假设p[j] = '*' 那么如果使用星号就等于dp[i - 1][j],如果不使用就等于dp[i][j - 1],假设为问号或者s和p匹配,那么就等于dp[i - 1][j - 1]

3.初始化数组:dp[0][0] = true,并且当p = '*'且s为空时,dp[0][i] = true

字符串匹配法:

设定两个标识位,分别标识当存在星号时,i 和 j 的位置。逻辑是假设为问号或者s和p匹配,那么就i++、j++,当是星号时,从匹配空遍历后面的s字符串,当发现不匹配时,就返回标识位继续遍历,直到最后。

代码:

动态规划法:

class Solution {
public:
    bool isMatch(string s, string p) {
        int n = s.size() , m = p.size();
        vector> dp(n + 1 , vector(m + 1));
        dp[0][0] = true;
        for(int i = 1; i <= m; i++) {
            if(p[i - 1] == '*')     dp[0][i] = true;
            else    break;
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(p[j - 1] == '*') {
                    dp[i][j] = dp[i][j - 1] | dp[i - 1][j];
                } else if(p[j - 1] == '?' || p[j - 1] == s[i - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                } 
            }
        }
        return dp[n][m];
    }
};

字符串匹配法:

class Solution {
public:
    bool isMatch(string s, string p) {
        int i = 0 , j = 0 , iStar = -1 , jStar = -1 , n = s.size() , m = p.size();
        while(i < n) {
            if(p[j] == '?' || s[i] == p[j]) {
                i++; j++;
            } else if(j < m && p[j] == '*') {
                jStar = j++;
                iStar = i;
            } else if(iStar >= 0) {
                i = ++iStar;
                j = jStar + 1;
            } else      return false;
        }
        while(j < m && p[j] == '*')     j++;
        return j == m;
    }
};

总结

  1. 动态规划数组中,i 和 j 分别表示的是s和p匹配的字符数量,所以在匹配字符串时记得要 -1 
  2. 字符串法中,当匹配完成后,如果p的结尾存在多余的星号时记得“删除”

 

你可能感兴趣的:(练习题记录,分类知识点学习)