LeetCode:10. Regular Expression Matching

在这里插入图片描述

老大难问题,终于算是理解了。
首先状态定义不难写(哈哈):
dp[i][j]: s[0->i-1] p[0->j-1],它们是不是符合。
难的是状态转移方程(又一次验证):
1.如果s[i-1]== p[j-1] || p[j-1] == ‘.’, dp[i][j] = dp[i-1][j-1]
2.如果p[j-1] == '*'并且重复0次,那么dp[i][j] = dp[i][j-2]
3.如果p[j-1] == '*'并且重复至少一次,那么dp[i][j] = dp[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == ‘.’)

比较难以理解的是3,这里尝试解释一下:
s: 0, 1, …, i-2, i-1
p: 0, 1, …, j-2, j-1
此时p[j-1]==’’,如果这个 * 重复至少一次,就说明1.s[i-1] == p[j-2] || p[j-2] == '.‘是需要的 2.看的是dp[i-1][j],而不是dp[i-1][j-1],因为如果只看dp[i-1][j-1]的话,那么就说明这个’'只重复了一次,但是这里需要包含不止一次的情况,所以要看dp[i-1][j]。而且dp[i-1][j]表示的是这个*重复了0 次或者多次,所以在加上这里的s[i-1],就表示1次或者更多。

class Solution {
public:
    bool isMatch(string s, string p) {
        int ssz = s.size(), psz = p.size();
        vector<vector<bool>> dp(ssz+1, vector<bool>(psz+1, false));
        dp[0][0] = true;
        for (int j = 1; j <= psz; ++j)
            if (p[j-1] == '*' && dp[0][j-2])
                dp[0][j] = true;
        for (int i = 1; i <= ssz; ++i)
            for (int j = 1; j <= psz; ++j) {
                if (p[j-1] == '*')
                    dp[i][j] = dp[i][j-2] || (dp[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == '.'));
                else 
                    dp[i][j] = dp[i-1][j-1] && (s[i-1] == p[j-1] || p[j-1] == '.');
            }
        return dp.back().back();
    }
};

另外这题比较坑爹的是题目没有说明不会出现一些边角情况:比如:
*不会出现在开头
*不会连续出现
容易导致想复杂了

posted @ 2019-09-16 10:16  于老师的父亲王老爷子  阅读(9)  评论(0编辑  收藏  举报