Skip to content

Latest commit

 

History

History
 
 

301.Remove-Invalid-Parentheses

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

301.Remove-Invalid-Parentheses

本题没有太高明的办法,基本就是靠搜索,数量级应该就是O(2^N).DFS和BFS均可。感觉对于在同一个数组或字符串里面搜若干个元素的话,DFS写起来更舒服一些。基本思想就是对于每一个s[i]都有“选用”(append到当前curStr中去)和“不选用”两种选择,然后依次递归下去。如果遇到curStr不合法的情况,就及时中断这条支路。

但本题最大的考点应该在于如何避免最后大量重复的结果。比如说我们想在“((()”里面最终得到"()",其实就有好几种DFS的路径。比如说"OOXX", "XOOX", "OXOX"(O表示不选,X表示选)。可见原字符串中的三个“(((”,可以有三种不同的路径得到最后只剩一个"("。如果无脑地对每个字符都尝试“选用”和“不选用”,那么最后势必要依靠字符串类型的集合来去重,效率会很低。

本题的精彩之处,是在于设计一种DFS路径选择机制,能够避开任何可能造成重复的路径。规则如下:

  1. 如果备选字符s[i]与已选字符串的最后一位相同,那么你必须选择使用这个字符,即curStr.append(s[i])
  2. 如果备选字符s[i]与已选字符串的最后一位不相同,那么你可以选择使用这个字符,也可以选择不使用,接下来的两条分叉递归处理。

上面规则的本质是,如果最终生成的字符串含有若干个相同的字符,那么这些相同字符在s中的顺序也必须是连续的,并且是最后的若干个连续的字符。

举个例子,如果s中有四个连续的左括号,我们选择保留下来两个左括号,那么我们对这四个左括号的选择一定是XXOO的形式,即我们只选择最后两个。而不能是OOXX,OXOX,OXXO,XOOX,XOXO这五种其他的形式。这样就避免了六种DFS搜索形式对应同一个最终结果的复杂局面。

Leetcode Link