给定括号字符串,我们必须做两种操作:
字符串的长度最大为30000.
最多只能进行操作 100000。
应该使用什么样的数据结构来解决这类问题?
Segment Tree是一个合适的数据结构吗?
如果是,应该如何使用它?
实施例
string =()((
no of operation = 4
答案 0 :(得分:1)
让每个(
为+1
,每)
为-1
。如果整个字符串的总和为零,则每个范围[0, k]
的总和为非负值,则平衡一串括号。
让我们为子串[i,j]
,sum
和min
定义两个函数。 sum
显而易见,min(i,j)
定义为所有sum(i,k)
k <= j
的最低要求。
所以
sum(i,k) = sum(i,j) + sum(j+1, k)
和
min(i,k) = MIN( min(i,j), sum(i,j) + min(j + 1, k) )
现在我们可以构建一个二叉树,其中叶子是+1
和-1
,而root是整个范围[0, N-1]
。对于每个节点,我们保留min
和sum
。
查询余额很明显:我们会检查root.min >= 0
和root.sum == 0
,所以O(1)
。
通过更新叶节点并将更改传播到根来完成翻转。不超过log(N)+1
个节点,每个更新都为O(1)
,因此O(logN)
。
答案 1 :(得分:0)
可以轻松检查字符串是否平衡的函数。单步执行字符串,如果满足“(”字符,则递增零初始化值,如果满足“()”则递减它)。如果结果为0并且在运行期间它从未低于0,则字符串是平衡的。 在字符串的第n个位置翻转括号是微不足道的。
这是javascript中的一个简单实现,它在循环中翻转字符串的随机字符,并在每次翻转后检查结果字符串的有效性。
http://jsbin.com/vagalijoca/edit?html,console
function checkbalanceness(str){
var res = 0;
for(i=0;i<str.length;i++) {
str[i]=="(" ? res++ : res--;
if (res < 0) break;
}
return res == 0;
}
function flipp(str, i){
if (i >= str.length) return str;
return str[i]=="(" ?
str.substr(0,i) + ")" + str.substr(i+1) :
str.substr(0,i) + "(" + str.substr(i+1) ;
}
//initial string
var curr = "()(())";
//operations to be executed
var ops = 40;
console.log('initial string: ' + curr + ' ' + checkbalanceness(curr));
console.log('operations: ' + ops);
console.log('start');
var ii;
var chartoflip;
for(ii=0;ii<ops;ii+=2){
chartoflip = (ii/2)%(curr.length);
curr = flipp(curr, chartoflip);
console.log((ii) + ' - flip char ' + chartoflip + ': ' + curr);
console.log((ii+1) + ' - checking ' + curr + ' ' + checkbalanceness(curr));
}
console.log('end');