[LeetCode] 10. Regular Expression Matching

来源:互联网 发布:知圆链条索具 编辑:程序博客网 时间:2024/06/15 06:45

思路1:
递归肯定会比较慢, 就直接上动态规划了. 要多建立一行和一列, 因为要考虑空字符串的情况.
flags[i][j]表示子串s[0…i - 1]是否匹配p[0…j - 1].
flags[0][0]一定是真, 因为空字符串一定能匹配空字符串.
除了第0项, 剩下的第0列一定都是假, 因为如果p是空字符串, 那么他就只能匹配空字符串而已.
除了第0项, 剩下的第0行要遵循以下三个条件才能是真:
1) 下标要大于1, 意思是子串必须长度大于等于2;
2) 当前字符必须是’*’;
3) 向前数2个, flags[0][j -2], 意思就是”x*”不重复的时候也要能匹配才可以
初始化工作算是结束了, 下面开始填满剩余的矩阵.
flags[i][j]为真要满足以下条件二选一:
1) 当当前字符为”*”时:
“x*”不重复的时候, 也就是flags[i][j - 2]的值为真;
“x*”至少重复一次的时候, 包括p的上一个字符和s的当前字符相同, 或者p的上一个字符为’.’;
和在重复的情况下, s的上一个子串也匹配
2) 当当前字符不为”*”时:
要看s的上一个子串和p的上一个子串是否匹配;
以及s当前字符和p的当前字符是否相等, 或者p当前字符是不是’.’.

bool isMatch(string s, string p) {    int slen = s.length(), plen = p.length();    bool flags[slen + 1][plen + 1];    flags[0][0] = true;    for (int j = 1; j <= plen; j++)        flags[0][j] = j > 1 && p[j - 1] == '*' && flags[0][j - 2];    for (int i = 1; i <= slen; i++)        flags[i][0] = false;    for (int i = 1; i <= slen; i++) {        for (int j = 1; j <= plen; j++) {            if (p[j - 1] == '*')                flags[i][j] = flags[i][j - 2]                     || (p[j - 2] == s[i - 1] || p[j - 2] == '.')                         && flags[i - 1][j];            else                flags[i][j] = flags[i - 1][j - 1] &&                             (p[i - 1] == s[i - 1] || p[i - 1] == '.');        }    }    return flags[slen][plen];}

第二个版本:
思路依然是动态规划, 但是因为每次我们最多只需要上一次的结果, 所以可以把O(m * n)的空间开销节省为O(n)的, 只开两个数组循环交替存取数据就好, 而不用开辟整个m * n的矩阵空间.

bool isMatch(string s, string p) {    int slen = s.length(), plen = p.length();    int prev = 0, cur = 0;    bool flags[2][plen + 1];    flags[0][0] = true;    for (int j = 1; j <= plen; j++)        flags[0][j] = j > 1 && p[j - 1] == '*' && flags[0][j - 2];    cur = 1 - cur;    for (int i = 1; i <= slen; i++) {        flags[cur][0] = false;        for (int j = 1; j <= plen; j++) {            if (p[j - 1] == '*')                flags[cur][j] = flags[cur][j - 2]                                || (p[j - 2] == s[i - 1] || p[j - 2] == '.')                                    && flags[prev][j];            else                 flags[cur][j] = flags[prev][j - 1]                                && (p[j - 1] == s[i - 1] || p[j - 1] == '.');        }        swap(cur, prev);    }    return flags[prev][plen];}
0 0
原创粉丝点击