边工作边刷题:70天一遍leetcode: day 39

Regular Expression Matching及变形

要点
fb的常考题, uber也考过。

思路: recursion是基本的结构: 假设s为待匹配string, p为pattern. 当前要匹配si和pi位置的char. 因为有的存在, 自然分成两种case: 就是有和没有. 如果不是, 只比较当前2个字符. 如果遇到*, 需要loop si当前位置所有向右(recursion)或者向左(dp)的相同char. 每一个会产生一个新的递归分支. 注意skip当前字符也是一个分支.

recursion:
base condition: 因为递归是向右, 所以如果pi超过pattern, 递归结束.
因为是和左边的字符关联的, 递归向右的情况, 其条件是p[pi+1]==''.
worst case: s: aa…aab, p: a…a: 每一层都要loop所有s中的a,loop中的每一个进入一个同样loop的层,形成一个tree structure,所以是O(2^n),space是O(n)

dp:
base condition: p向右移动
以当前字符是否为*作为条件

class Solution(object):
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        dp = [[False for j in range(len(p)+1)] for i in range(len(s)+1)]
        dp[0][0] = True

        for i in range(len(s)+1):
            for j in range(1, len(p)+1):
                if p[j-1]!='*':
                    if i==0: dp[i][j]=False
                    else:
                        dp[i][j]=(s[i-1]==p[j-1] or p[j-1]=='.') and dp[i-1][j-1]
                else:
                    dp[i][j]=dp[i][j-2]
                    ii = i
                    while ii>0 and (s[ii-1]==p[j-2] or p[j-2]=='.'):
                        if dp[ii-1][j-2]: 
                            dp[i][j]=True
                            break
                        ii-=1
        return dp[len(s)][len(p)]
                    
posted @ 2016-04-06 12:06  absolute100  阅读(109)  评论(0编辑  收藏  举报