Mickey's Blog ·

【leetCode】正则匹配函数-day2

到了今天下午我还是没想出来啊,已经知道了是要使用递归分解问题进行求解,但我始终不能分析明白的就是分解问题,分而治之我之前所写的所有算法都是分割的很清晰,很稳定,相互之间的条件和结果没有关联,举个例子,

s = aaabbb

p = a.b*

这个时候有很多种可能,这个.*可以划分给左边aaa 也可以划分给右边bbb,不会影响结果。这就导致我们无法清晰稳定的划分问题,其实这里可以这么划分

aaa a*

'' .*

bbb b*

但是这个例子比较简单,如果是这样呢

s = bbbb

p = .*bb

这个我么你能看出来是匹配成功的,但是你是怎么看出来的呢,相信大家仔细想一下自己的判断过程,是看完了整个p串才能得出结论,但如果我们使用分治法,将他分成小的问题,他们互相的结果勉强可以互相叠加返回,但是切割条件真的很难定。最后我去看了一个分析的博客。提到了一个正是解决我问题的算法,叫做DP算法——动态规划(dynamic programming)。

http://blog.csdn.net/cangchen/article/details/45044811

他的主体思想和分治法相似,但和分治法最大的差别就是:经分解后的子问题往往不是互相独立的(即下一个子阶段的求解释建立在上一个子阶段的解的基础上进行的,进行进一步的求解)

同时我也看了其他博主的一些答案,对这些不确定如何切割的问题,他们类似穷举了所有可能,只要有一个切割方式是可行的就返回正确。这也确实是一个简单有效的解法,在这个问题复杂度下运算量暂时不是最优先考虑的问题,那么其他答主大概是怎么做的呢,就以上面的例子来看。

s = bbbb

p = .*bb

首先开始是s第一个字符是b p第一个匹配是通配符'.',于是匹配成功,接下来开始进入匹配模式,逐步向后匹配,注意,我之前的想法肯定是一直匹配直到b消失,但是答主的算法每次匹配完都重新开始一个分支,尝试着结束,看看能否继续进行。也就是

p[0]匹配到一个b,之后分为两个分支,一个继续匹配.,一个停止匹配.。如论哪个走到最后匹配成功都返回true;

这个算法显然会走完所有可能,也不对接下来的匹配串进行判断,直接暴力穷举,但真的可以接出来,性能也还行。等我做一个关于DP算法的文章然后尝试着拿这个DP思想,更有效率的接这个正则问题。

最后附上穷举的答案

无标题.png

这个算法是CPP,但可读性很高大家应该也能读的懂

DP解法传送门:https://discuss.leetcode.com/topic/17852/9-lines-16ms-c-dp-solutions-with-explanations