问题:
从字符串中删除多余的括号 例如
((a+b))*c => (a+b)*c
(a+b)+c => (a+b)+c
((a+b)/(c+d)) => ((a+b)/(c+d))
(a+(((b-c)))*d) => (a+(b-c)*d) and so on.
我提出了以下解决方案:
方法:我扫描字符串并记住(使用地图)左括号的索引以及它是否是额外的(默认情况下是额外的)。如果我找到一个右括号,我从地图中检查相应的左括号,如果它是额外的,则删除两者。
void removeExtraParentheses(string& S){
map<int, bool> pmap;
for(int i = 0; i < S.size(); i++){
map<int, bool>::iterator it;
if(S.at(i) == '('){
pmap[i] = true;
}
else if(S.at(i) == ')'){
it = pmap.end();
it--;
if(!(*it).second){
pmap.erase(it);
}
else{
S.erase(S.begin() + i);
S.erase(S.begin() + (*it).first);
pmap.erase(it);
i = i - 2;
}
}
else{
if(!pmap.empty()){
it = pmap.end();
it--;
(*it).second= false;
}
}
}
}
时间复杂度:O(n2)
空间:O(n)
我对我的解决方案不太满意,因为我正在使用额外的存储并在二次时间内完成它。
我们可以在O(n)时间和O(1)空间中这样做吗?如果不是最好的人能做什么?
答案 0 :(得分:2)
构建表达式树,然后用最小值重新生成表达式 括弧。原文中的任何括号都不在 生成是不必要的。
一个简单,几乎正确的解决方案是分配优先权
每个运营商。然后,您可以在任何时候直接使用括号
在您正在处理的节点下是一个较低的运算符
优先级高于节点的优先级;例如,如果你在*
(乘法)节点,并且两个子节点之一具有+
(附加)节点。加上一些逻辑来处理左或右绑定:如果
您位于+
节点,右侧节点也是+
节点,您
需要括号。
这只是部分正确,因为有一些结构 C ++实际上不能映射到优先语法:其中一些 我想到了类型铸造结构,或三元运算符。在 但是,至少在三元运算符的情况下,特殊处理 并不难。
编辑:
关于你的大问题:这显然不是O(1)in
space,因为你需要在内存中构造整个表达式。一世
不要认为O(1)的记忆是可能的,因为可能,你可以
有无限的嵌套,你不能告诉括号是否
必要与否,直到不确定的时间之后。我实际上并不是这样
分析它,但我认为它是O(n)及时。上限就是
节点数是n
(字符串的长度),您需要访问
每个节点只有一次。
答案 1 :(得分:2)
或多或少在网上找到......
给定输入:((A + B)* C) 预期产出:(A + B)* C
假设:
下面的伪代码:
将中缀表达式转换为RPN(例如Shunting-yard algo O(n))
AB+C*
仅在队列Q
(前)+ -------- *(后方)
S
所有应该是O(n)。
答案 2 :(得分:0)
我以为我会刺伤这个。这是我想到的问题的解决方案。请注意,这是伪代码,并不意味着直接运行。
(实际上,它更像是C ++ - ish,但是自从我上次编写实际的C ++以来已经有一段时间了,当我打算通过一种算法时,我并不想努力使一切正确。)
queue<tuple<int, bool> > q = new queue<tuple<int, bool> >();
for (int i = 0; i < str.length; i++)
{
char a = str.charAt(i);
if (a == '(')
{
q.push(new tuple<int, bool>(i, false));
}
else if (a == ')')
{
if (q.top().bool)
{
// remove top.int and i from string
}
q.pop();
q.top().bool = true;
}
else
{
q.top().bool = false;
}
}
它在O(n)
中完成工作并使用O(n)
空间(实际上,使用的空间量实际上是基于字符串中最深的嵌套级别,但保证低于n
)
(请注意,// remove top.int and i from string
实际上无法完成O(1)
。但是,如果您获得了一点创意,则可以在O(1)
中执行类似操作。
例如,您实际上可以为输出构建一个字符列表并存储迭代器而不是int,然后您可以删除O(1)中的两个字符。最后,您可以通过迭代O(n)中的列表来构建最终字符串。另一种解决方案是实际处理DummyOrCharacters的数组(或向量),它们是虚拟的,不包含任何内容或包含字符。再一次,你可以在O(1)
中用假人替换一个角色。再次,您将遍历结构并在O(n)
)