算法 递归 回溯 搜索树
题意是在规则之下的xxxxx…的最大长度
-
规则1:
()
的意思是有括号的先算括号里面的,优先级最高,把括号计算的结果在和括号外的字符拼接,即括号是相对独立,完整的个体 -
规则2:
|
的意思是|
这个符号两侧的字符串只能选其中一个,由于这题要求能拼接的字符串最长,因此应该选择字符|
字符串xxx...
长度较大的一侧
如果递归的问题想不清楚的话,就画一颗递归搜索树 –yxc
比如样例中的字符串((xx|xxx)x|(x|xx))xx
对应的递归搜索树如下
时间复杂度 $O(N)$
每个字符只会进栈一次,出栈一次,因此是线性的时间复杂度
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std ;
int k ;
string str ;
int dfs(){
int res = 0 ;
while(k<str.size()){
if(str[k] == '('){
k ++ ;
res += dfs() ;
k ++ ;
}else if(str[k] == ')'){
// k ++ ;
break ;
}else if(str[k] == '|'){
k ++ ;
res = max(res,dfs()) ;
}else{
k ++ ;
res ++ ;
}
}
return res ;
}
int main(){
cin >> str ;
cout << dfs() << endl ;
return 0 ;
}
(xxxx|xxx) 这样理解,假如在|层里面遇到)就返回,确实能算出来|左右两边的值的最大值,但在|里面遇到),k++的话,回到( 的搜索完毕的那一层,(就遇不到)了,就是说()内的值无法正确更新;
这里的递归分两种情况,一种是括号一种是
|
,括号是匹配的,而|
只有一个怎么写出来的 ,还是觉很难啊 。hah orz,
我也觉得,感觉代码跟二叉搜索树对不上qwq
用栈来理解似乎更好理解一点
树应该是一种存储数据的结构可以用链表或数组存,这应该就是单纯dfs递归算法
递归搜索的过程和树的形状类似,可以用树形象化理解
我第一次写也在’)’里k,Orz。我的理解是’(‘和’)’搜完后必须在同一层递归栈内。如果在搜索’|’层时,遇到’)’就执行k,那么’)’就无法回溯到正确的搜索层数了,即出现把右括号过滤了情况。
括号是匹配的,而
|
只有一个唉,这种递归感觉能看懂就是自己写不出来
讨论里第一是大佬说看不懂,题解里佬你还是第一
这个为什么要在每一层里都让res=0啊?
每次进递归都是一次“新”的匹配
还是没懂为什么 不能在’)’里面k++啊? 指点一波
因为 在 “|” 的分支递归结束的时候,如果在 “)”的分支里k++的话,会把右括号过滤,答案就不对了
因为在
(
的进入递归的函数在回溯的时候k了,因此不能再)
时在k,(
进入递归和|
进入递归的情况不一样k ;
res += dfs() ;
k ;
就是第三个行的k++
前来%%%