Given a string s of opening and closing brackets '(' and ')' only, find an equal point in the string. An equal point is a position k (0-based) such that the number of opening brackets before position k is equal to the number of closing brackets from position k to the end of the string. If multiple such points exist, return the first valid position. If no such point exists, return -1.
Note: The string can be split at any position from 0 to n, where n is the length of the string.

Examples:
Input: s = "(())))("
Output: 4
Explanation: After index 4, string splits into (()) and ))(. The number of opening brackets in the first part is equal to the number of closing brackets in the second part.Input: s = "))"
Output: 2
Explanation: After index 2, the string splits into "))" and an empty string. The number of opening brackets in the first part is 0 and the number of closing brackets in the second part is also 0.
Table of Content
[Naive Approach] Using Nested Loops – O(n^2) Time and O(1) Space
The idea of this approach is to check every possible index of the string as a potential split point.
For each index k, we compute:
- The number of opening brackets '(' in the range [0, k-1]
- The number of closing brackets ')' in the range [k, n-1]
- If both counts become equal at any index, we return that index. If no such index exists, we return -1.
#include <bits/stdc++.h>
using namespace std;
int findIndex(string& s) {
int n = s.size();
for (int i = 0; i <= n; i++) {
int openCnt = 0, closeCnt = 0;
// Count opening brackets before index i
for (int j = 0; j < i; j++) {
if (s[j] == '(')
openCnt++;
}
// Count closing brackets from index i onward
for (int j = i; j < n; j++) {
if (s[j] == ')')
closeCnt++;
}
if (openCnt == closeCnt)
return i;
}
return -1;
}
int main() {
string s = "(())))(";
cout << findIndex(s) << endl;
return 0;
}
class GFG {
static int findIndex(String s) {
int n = s.length();
for (int i = 0; i <= n; i++) {
int openCnt = 0, closeCnt = 0;
// Count opening brackets before index i
for (int j = 0; j < i; j++) {
if (s.charAt(j) == '(')
openCnt++;
}
// Count closing brackets from index i onward
for (int j = i; j < n; j++) {
if (s.charAt(j) == ')')
closeCnt++;
}
if (openCnt == closeCnt)
return i;
}
return -1;
}
public static void main(String[] args) {
String s = "(())))(";
System.out.println(findIndex(s));
}
}
def findIndex(s):
n = len(s)
for i in range(n + 1):
openCnt = 0
closeCnt = 0
# Count opening brackets before index i
for j in range(i):
if s[j] == '(':
openCnt += 1
# Count closing brackets from index i onward
for j in range(i, n):
if s[j] == ')':
closeCnt += 1
if openCnt == closeCnt:
return i
return -1
if __name__ == "__main__":
s = "(())))("
print(findIndex(s))
using System;
class GFG {
static int findIndex(string s) {
int n = s.Length;
for (int i = 0; i <= n; i++) {
int openCnt = 0, closeCnt = 0;
// Count opening brackets before index i
for (int j = 0; j < i; j++) {
if (s[j] == '(')
openCnt++;
}
// Count closing brackets from index i onward
for (int j = i; j < n; j++) {
if (s[j] == ')')
closeCnt++;
}
if (openCnt == closeCnt)
return i;
}
return -1;
}
static void Main() {
string s = "(())))(";
Console.WriteLine(findIndex(s));
}
}
function findIndex(s) {
let n = s.length;
for (let i = 0; i <= n; i++) {
let openCnt = 0, closeCnt = 0;
// Count opening brackets before index i
for (let j = 0; j < i; j++) {
if (s[j] === '(')
openCnt++;
}
// Count closing brackets from index i onward
for (let j = i; j < n; j++) {
if (s[j] === ')')
closeCnt++;
}
if (openCnt === closeCnt)
return i;
}
return -1;
}
// drive code
let s = "(())))(";
console.log(findIndex(s));
Output
4
[Expected Approach] Counting Total Closing Brackets – O(n) Time and O(1) Space
The idea of this approach is to first count how many closing brackets are in the string, and then go through the string step by step while updating the counts as we move.
- First, count the total number of closing brackets ')' in the string.
- Maintain two variables: openCnt (opening brackets before current index) and closeCnt (closing brackets from current index to end).
- Traverse the string and update counts at each step.
- If openCnt == closeCnt, return that index; otherwise, return -1 if no such index is found.
Consider the string s = "(())))("
Step1: First count total closing brackets, so total ')' = 4, therefore initially openCnt = 0 and closeCnt = 4.
Step 2: Traverse the string:
- Index 0 -> '(' -> openCnt = 1, closeCnt = 4 (not equal)
- Index 1 -> '(' -> openCnt = 2, closeCnt = 4 (not equal)
- Index 2 -> ')' -> openCnt = 2, closeCnt = 3 (not equal)
- Index 3 -> ')' -> openCnt = 2, closeCnt = 2 (not equal, because check happens before updating)
- Index 4 -> ')' -> openCnt = 2, closeCnt = 2 (equal)
Therefore, the answer is: 4
#include <bits/stdc++.h>
using namespace std;
int findIndex(string& s) {
int n = s.size();
int openCnt = 0, closeCnt = 0;
// Count total closing brackets
for (int i = 0; i < n; i++) {
if (s[i] == ')')
closeCnt++;
}
for (int i = 0; i <= n; i++) {
// Equal point found
if (openCnt == closeCnt)
return i;
if (i < n) {
// Count opening brackets before next index
if (s[i] == '(')
openCnt++;
// Count closing brackets from next index onward
if (s[i] == ')')
closeCnt--;
}
}
return -1;
}
int main() {
string s = "(())))(";
cout << findIndex(s) << endl;
return 0;
}
class GFG {
static int findIndex(String s) {
int n = s.length();
int openCnt = 0, closeCnt = 0;
// Count total closing brackets
for (int i = 0; i < n; i++) {
if (s.charAt(i) == ')')
closeCnt++;
}
for (int i = 0; i <= n; i++) {
// Equal point found
if (openCnt == closeCnt)
return i;
if (i < n) {
// Count opening brackets before next index
if (s.charAt(i) == '(')
openCnt++;
// Count closing brackets from next index onward
if (s.charAt(i) == ')')
closeCnt--;
}
}
return -1;
}
public static void main(String[] args) {
String s = "(())))(";
System.out.println(findIndex(s));
}
}
def findIndex(s):
n = len(s)
openCnt = 0
closeCnt = 0
# Count total closing brackets
for i in range(n):
if s[i] == ')':
closeCnt += 1
for i in range(n + 1):
# Equal point found
if openCnt == closeCnt:
return i
if i < n:
# Count opening brackets before next index
if s[i] == '(':
openCnt += 1
# Count closing brackets from next index onward
if s[i] == ')':
closeCnt -= 1
return -1
if __name__ == "__main__":
s = "(())))("
print(findIndex(s))
using System;
class GFG {
static int findIndex(string s) {
int n = s.Length;
int openCnt = 0, closeCnt = 0;
// Count total closing brackets
for (int i = 0; i < n; i++) {
if (s[i] == ')')
closeCnt++;
}
for (int i = 0; i <= n; i++) {
// Equal point found
if (openCnt == closeCnt)
return i;
if (i < n) {
// Count opening brackets before next index
if (s[i] == '(')
openCnt++;
// Count closing brackets from next index onward
if (s[i] == ')')
closeCnt--;
}
}
return -1;
}
static void Main() {
string s = "(())))(";
Console.WriteLine(findIndex(s));
}
}
function findIndex(s) {
let n = s.length;
let openCnt = 0, closeCnt = 0;
// Count total closing brackets
for (let i = 0; i < n; i++) {
if (s[i] === ')')
closeCnt++;
}
for (let i = 0; i <= n; i++) {
// Equal point found
if (openCnt === closeCnt)
return i;
if (i < n) {
// Count opening brackets before next index
if (s[i] === '(')
openCnt++;
// Count closing brackets from next index onward
if (s[i] === ')')
closeCnt--;
}
}
return -1;
}
// drive code
let s = "(())))(";
console.log(findIndex(s));
Output
4