# **Balanced Parentheses and Brackets**
A string w of parentheses ( and ) and brackets [ and ] is balanced if it satisfies one of the following conditions:
* w is the empty string
* w = (x) for some balanced string x
* w = [x] for some balanced string x
* w = xy (concatenation) for some balanced strings x and y
For example, the string
w=([()][]())[()()]() is balanced, because w=xy, where x=([()][]()) and y=[()()]()
# **Solution 1**
**Problem**
Describe and analyze an algorithm to determine whether a given string of parentheses and brackets is balanced.
**Algorithm**
The following algorithm uses the function ```isBalanced(x)``` to correctly determine if a given string of parentheses and brackets is balanced. The function uses a stack to keep track of matching parentheses or brackets. If an open bracket or parenthesis appears, it is pushed onto the stack. If a closing bracket or parenthesis appears, it is compared to the top of the stack to check if it matches.
```
fun isBalanced(x){
var S = [];
for(int i = 0; i < len(x); i++){
if(x[i] == '(' or x[i] == '['){
push(S, x[i]);
}
else if(x[i] == ')'){
if(len(S) == 0 or S[len(S) - 1] != '(')
return false;
pop(S);
}
else if(x[i] == ']'){
if(len(S) == 0 or S[len(S) - 1] != '[')
return false;
pop(S);
}
}
if(len(S) == 0){
return true;
}
return false;
}
```
**Correctness Proof**
Goal: Prove that isBalanced(x) correctly returns true if x is balanced.
Base Case:
x is empty: the loop does not execute and the stack is empty --> returns true
Inductive Hypothesis: Assume the algorithm correctly checks if a string is balanced for all strings shorter than n
1. if '(' or '[' appears, the open bracket is recorded
2. if ')' or ']' appears, the closing bracket is matched to the most recently stored open bracket
3. the stack will be empty at the end only if each opening bracket has a matching closing bracket
By induction, the algorithm correctly determines if a string is balanced
**Time Complexity**
Each character in the string is processed once
T(n) = O(n)
# **Solution 2**
**Problem**
Describe and analyze an algorithm to compute the length of a longest balanced subsequence of a given string of parentheses and brackets.
**Algorithm**
The following algorithm uses the function ```longestBalancedSubseq(x)``` to correctly find the length of the longest balanced subsequence of a given string of parentheses and brackets. The function uses a stack to keep track of the base index of the current subsequence. When a matching closing bracket is found, the stack is popped and the length is updated as the new longest length. If there is a bracket that does not match, its index is set as the new base index for the next subsequence.
```
fun longestBalancedSubseq(x) {
var s = [];
push(s, -1);
var max_len = 0;
for (var i = 0; i < len(x); i++) {
var ch = x[i];
if (ch == '(' or ch == '[') {
push(s, i);
}
else { // closing bracket
if (len(s) > 0) {
var top_idx = top(s);
if ((ch == ')' and x[top_idx] == '(') or
(ch == ']' and x[top_idx] == '[')) {
pop(s);
if (len(s) > 0)
max_len = max(max_len, i - top(s));
else
push(s, i);
}
else {
push(s, i);
}
}
else {
push(s, i);
}
}
}
return max_len;
}
```
**Correctness Proof**
Goal: Prove that longestBlancedSubseq(x) correctly finds and returns the length of the longest balanced subsequence
Base Case:
* x is empty: no iterations, s = [-1], max_len = 0 --> correct
Inductive Hypothesis:
Assume the algorithm correctly finds and computes the length of the longest balanced subsequence for all strings shorter than n.
1. if there is an opening bracket --> push index into stack
2. if there is a matching closing bracket --> pop opening bracket index and compute length of current balanced segment --> ```i - top(s)```
3. if a bracket that doesn't match appears --> reset base index --> ```push(s, i)```
The algorithm correctly finds and computes the longest balanced subsequence length.
**Time Complexity**
Each character is pushed and popped from the stack at most once
T(n) = O(n)