Balanced Parentheses Problem Using Stack in DSA Go - Time & Space Complexity
We want to know how the time needed to check balanced parentheses changes as the input string grows.
How does the number of steps grow when the string gets longer?
Analyze the time complexity of the following code snippet.
func isBalanced(s string) bool {
stack := []rune{}
for _, ch := range s {
if ch == '(' {
stack = append(stack, ch)
} else if ch == ')' {
if len(stack) == 0 {
return false
}
stack = stack[:len(stack)-1]
}
}
return len(stack) == 0
}
This code checks if parentheses in a string are balanced using a stack.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each character in the string once.
- How many times: Exactly once for each character (n times for string length n).
As the string gets longer, the code checks each character one by one.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The number of steps grows directly with the string length.
Time Complexity: O(n)
This means the time to check grows in a straight line with the input size.
[X] Wrong: "The stack operations inside the loop make this more than linear time."
[OK] Correct: Each character is pushed or popped at most once, so stack operations add only constant work per character, keeping time linear.
Understanding this linear time check shows you can handle common stack problems efficiently, a key skill in many coding challenges.
"What if the input string included other characters besides parentheses? How would the time complexity change?"
Practice
Balanced Parentheses Problem?Solution
Step 1: Understand the role of stack in parentheses matching
The stack stores opening parentheses as they appear to check if each closing parenthesis matches the last opened one. Counting or reversing parentheses does not help in matching pairs correctly; sorting changes the order and breaks the sequence.Final Answer:
To keep track of opening parentheses and match them with closing ones -> Option AQuick Check:
Stack usage = matching parentheses [OK]
- Thinking stack counts parentheses instead of matching
- Assuming stack reverses the string
- Believing sorting helps in matching parentheses
stack?Solution
Step 1: Recall how to add elements to a slice in Go
In Go, slices use the built-inappendfunction to add elements at the end. Sincestackis a slice,stack = append(stack, '(')correctly adds '(' to the top.Final Answer:
stack = append(stack, '(') -> Option AQuick Check:
Use append to push in Go slices [OK]
- Using non-existent methods like push or add on slices
- Forgetting to assign back after append
- Using incorrect method names
"([])" has balanced parentheses?func isBalanced(s string) bool {
stack := []rune{}
for _, ch := range s {
if ch == '(' || ch == '[' {
stack = append(stack, ch)
} else if ch == ')' {
if len(stack) == 0 || stack[len(stack)-1] != '(' {
return false
}
stack = stack[:len(stack)-1]
} else if ch == ']' {
if len(stack) == 0 || stack[len(stack)-1] != '[' {
return false
}
stack = stack[:len(stack)-1]
}
}
return len(stack) == 0
}
fmt.Println(isBalanced("([])"))Solution
Step 1: Trace the stack operations for "([])"
Push '(' then push '['; on encountering ']', pop '['; on encountering ')', pop '('; stack ends empty, so function returns true indicating balanced parentheses.Final Answer:
true -> Option CQuick Check:
Stack empty after matching = true [OK]
- Not popping matching opening bracket
- Confusing bracket types
- Ignoring empty stack check before pop
func isBalanced(s string) bool {
stack := []rune{}
for _, ch := range s {
if ch == '(' {
stack = append(stack, ch)
} else if ch == ')' {
if len(stack) == 0 || stack[len(stack)-1] != ')' {
return false
}
stack = stack[:len(stack)-1]
}
}
return len(stack) == 0
}Solution
Step 1: Analyze the popping condition for closing parenthesis
The code checks if the top of stack is ')', but it should check for '(' to match correctly. Since stack stores '(', checking for ')' fails to match and returns false incorrectly.Final Answer:
The condition checks for ')' instead of '(' when popping -> Option BQuick Check:
Match top stack with '(' for ')' closing [OK]
- Checking wrong character on stack top
- Not handling empty stack before pop
- Ignoring matching pairs logic
"{[()()]()}", which includes curly braces {}, square brackets [], and parentheses (), how should the stack-based algorithm be modified to correctly check for balanced parentheses of all three types?Solution
Step 1: Extend push logic for all opening brackets
Push '{', '[', '(' onto the stack when encountered to track all opening brackets. When encountering '}', ']', or ')', check if the top of the stack matches '{', '[', or '(' respectively before popping.Final Answer:
Add conditions to push '{', '[', '(' and pop matching '}', ']', ')' accordingly -> Option DQuick Check:
Match all bracket types with stack push/pop [OK]
- Ignoring curly braces in the algorithm
- Using multiple stacks unnecessarily
- Replacing stack with queue which breaks LIFO logic
Ready to prove it?
Pass the test and this pattern moves unknown
