我遇到了这个问题但无法解决。
任务是在一组开/关括号中找到一个合适的索引,其中第一个k字符中的左括号数=剩余N-k个字符中右括号的数量。
防爆。
“(()))))(”k将是5,因为前5个字符“(()))”有2 打开括号,剩下的“))(”有2个右括号。
另一个例子:
“()))()”k将是4.
k是独一无二的。解决方案应该是O(N)。
答案 0 :(得分:4)
分别使用指向第一个和最后一个字符的两个索引。
虽然两个索引没有相互交叉,但按以下方式移动:
返回左侧索引。
这是JavaScript中的一个实现,它运行您给出的两个示例的算法:
function partition(s) {
var i = 0;
var j = s.length - 1;
while (i <= j) {
if (s[i] !== '(') {
i++;
} else if (s[j] !== ')') {
j--;
} else {
i++;
j--;
}
}
return i;
}
console.log(partition("(()))))("));
console.log(partition("()))()"));
&#13;
随着索引在循环的每次迭代中彼此靠近,最多只有 n 次迭代。
答案 1 :(得分:3)
在预处理阶段,您可以计算字符串中的所有右括号(我们称之为c
)。然后处理从左边开始的每个字符。我们用seenOpening
表示已处理的左括号的数量,用unseenClosing
表示尚未处理的右括号的数量。最初为seenOpening = 0
和unseenClosing = c
。处理完每个字符后,根据括号的类型递增seenOpening
或递减unseenClosing
。每当seenOpening == unseenClosing
终止并返回您已处理的最后一个字符的索引时。
答案 2 :(得分:1)
这是一个Java解决方案:
public int getIndexOnMatchingBracketCount(String str) {
int closingBracket = 0;
int openingBracket = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == ')') {
closingBracket++;
}
}
for (int i = 0; i < s.length(); i++) {
if (openingBracket == closingBracket) {
return i;
}
char c = s.charAt(i);
if (c == ')') {
closingBracket--;
} else if (c == '(') {
openingBracket++;
}
}
return -1
}
答案 3 :(得分:0)
如果我们被允许使用O(n)
空格,我们可以在O(n)
中使用最少的逻辑非常轻松地完成此操作(如python
中所示):
def find_index(str):
n = len(str)
# O(n) space: no. of '(' in first k+1 and no. of ')' in last n-k characters
opening_in_first_k, closing_in_last_n_k = [0]*n, [0]*n
for i in range(1, n): # O(n) time
opening_in_first_k[i], closing_in_last_n_k[n-1-i] = opening_in_first_k[i-1] + (str[i] == '('), \
closing_in_last_n_k[n-i] + (str[n-1-i] == ')')
for i in range(n): # O(n) time
if opening_in_first_k[i] == closing_in_last_n_k[i+1]:
return i
return -1
print find_index("(()))))(")
# 5
print find_index("()))())")
# 4