这道题需要列举出所有可能的组合,所以第一想法是用递归:如果当前的字符是”(“, 就要考虑这个字符加入最终解和不加入最终解的情况(加入最终解的情况要先考虑这样才能产生最长的解);如果当前的字符是”)”, 也分这两种情况考虑,只是”)”加入最终解的时候要考虑一个限制条件,即加入后”)”的数量不能大于”(“的数量(这一点用变量cnt来控制);如果当前的字符是非括号之外的其他字符,就保留该字符进行递归。代码如下:
上面的版本可以通过,但是效率低(612ms),被鄙视了。想了一下可能的改进途径:
-
对于字符串参数,用引用代替值传递,避免拷贝。但递归结束后要把该字符串还原。(实践证明使用引用效果很明显)
-
对于连在一起重复出现的”(“或”)”,递归时只要考虑第一个出现的”(“或”)”即可,避免多次递归调用产生重复的结果
-
用一个数组(rpCnt)记录从当前位置到字符串结尾右括号”)”出现的次数。这主要是对当前字符为左括号”(“时进行剪枝:如果当前未配对的左括号”(“个数大于或等于后面的右括号”)”数,就不再对该左括号”(“进行递归。
-
如果字符串开头出现”)”或者结尾出现”(“,这些字符肯定不会出现在最后结果中。可以在递归前把它们删掉
代码如下:
改进之后的提升效果明显(8ms)。