Balanced Tree Span Calculator — Problem Statement & Solution Guide
Problem Description
You are given a single string s consisting solely of the characters '(' and ')'. The string is guaranteed to be a balanced parentheses expression. Treat this expression as a representation of a binary tree where each pair of matching parentheses denotes a node. The score of the tree is defined recursively:
* The simplest node "()" has a score of 1.
* If a node contains a single child expression A inside its parentheses, its score is twice the score of A.
* If a node contains two consecutive child expressions A and B inside its parentheses, its score is the sum of the scores of A and B.
Your task is to compute the score of the entire expression.
**Input**
A single line containing the string s.
**Output**
A single integer: the score of the expression.
The length of s can be up to 10⁵, and the score will fit in a 64‑bit signed integer.
DSA Pattern Breakdown
DSA Pattern Breakdown
"Balanced Tree Span Calculator"
WHY DOES IT MATTER?
Understanding how to translate recursive definitions into iterative stack operations is a core skill for tackling many parsing and expression‑evaluation problems, especially when input size can be large and recursion depth may cause stack overflow.
OPTIMIZATION CHALLENGE
The key insight is that the score of a node depends only on the aggregate score of its immediate children, allowing us to collapse the inner computation at the moment we close a parenthesis, thus avoiding repeated scans or deep recursion.
REAL-WORLD CONNECTION
The algorithm mirrors how compilers parse nested language constructs (e.g., block scopes or XML tags) using a push‑down automaton, and it also resembles depth‑based aggregation in distributed tracing where nested spans contribute exponentially to total latency.
During an interview, write the stack logic first on paper, then convert the pop‑until‑sentinel loop into a simple accumulator; this keeps the code short, avoids off‑by‑one errors, and demonstrates clear mental mapping from the recursive definition to an iterative process.
COMPLEXITY AT A GLANCE
O(n)O(n)Core Theory — Why This Approach?
The problem maps a balanced parentheses string to a binary tree where each matching pair of parentheses represents a node. The score is defined recursively: a leaf node "()" contributes 1, a node wrapping a single subtree A contributes twice the score of A (i.e., "(A)" = 2·score(A)), and concatenated sibling subtrees contribute additive scores (i.e., "AB" = score(A) + score(B)). This recursive definition mirrors the classic "Score of Parentheses" problem and can be evaluated efficiently using a stack that tracks the current nesting depth. A naive recursive parser would re‑scan the string for matching pairs, leading to O(n²) time on deep nesting because each call would need to locate its matching closing parenthesis. The optimal paradigm leverages a single left‑to‑right pass, pushing markers for '(' onto a stack and collapsing scores when a ')' is encountered, thereby achieving linear time.
The stack‑based solution works because the most recent '(' always pairs with the next ')', which aligns perfectly with LIFO semantics. When a ')' is read, we pop elements until we encounter the sentinel for the matching '('; the accumulated inner score (or zero for an empty pair) is then transformed according to the rule (empty → 1, non‑empty → 2·innerScore) and pushed back as the score of the completed subtree. This incremental aggregation eliminates the need for explicit recursion or repeated scanning, ensuring O(n) time and O(n) auxiliary space in the worst case (when the string is fully nested).
Interview Questions on This Problem
Q1How would you compute the score of a balanced parentheses string in a single pass without recursion?
Use a stack to store intermediate scores. Push a sentinel (e.g., 0) for each '('; when encountering ')', pop scores until the sentinel, compute the node's score as 1 if no inner score exists or 2·innerScore otherwise, then push the result back. The final stack sum is the answer.
Q2Why does the naive recursive approach degrade to O(n²) on inputs like "((((...))))"?
Each recursive call must locate its matching ')' by scanning forward, which costs O(k) for a subtree of size k. Summing over all depths yields a harmonic series that approximates O(n²) for deep nesting.
Q3Can you modify the stack solution to use O(1) extra space while still running in O(n) time?
Yes, by tracking the current depth and using the fact that a leaf "()" contributes 2^depth to the total score. Increment depth on '(' and, when a ')' follows a '(', add 1 << depth to the answer, then decrement depth. This eliminates the explicit stack.
Examples
Input
()
Output
1
Explanation: The expression is the simplest node, so its score is 1.
Input
(())
Output
2
Explanation: The outer node contains one child "()". Score = 2 * 1 = 2.
Input
()()
Output
2
Explanation: Two consecutive nodes "()" and "()". Score = 1 + 1 = 2.
Input
(()(()))
Output
6
Explanation: Outer node contains two children: "()" (score 1) and "(())" (score 2). Sum = 3, then outer node doubles it: 2 * 3 = 6.
Input
((()))
Output
4
Explanation: Outer node contains one child "(())" (score 2). Score = 2 * 2 = 4.
Constraints
- 1 <= s.length <= 100000
- s contains only '(' and ')', and is a balanced parentheses string
- The computed score fits in a 64‑bit signed integer
Optimal Approach & Strategy
Iterate once with a stack, collapsing scores as soon as a closing parenthesis is seen, turning the recursive definition into constant‑time stack operations per character.
Brute Force Approach
Recursively find each matching '(' and ')' pair, compute the score of the inner substring, and combine according to the rules, which leads to repeated scanning of the same characters.
Verified Code Solutions
function solution(nums) {
let sum = 0;
for (let num of nums) {
sum += num;
}
return sum;
}class Solution {
public:
int solution(vector<int> nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
return sum;
}
};class Solution {
public int solution(int[] nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
return sum;
}
}def solution(nums):
sum = 0
for num in nums:
sum += num
return sumfunction solution(nums) {
let sum = 0;
for (let num of nums) {
sum += num;
}
return sum;
}Asked in Top Tech Interviews
Solve in Interative Editor
Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.