A stack is a last-in-first-out (LIFO) structure. In Go,
a slice works as a stack: append to push, slice the
last element to pop.
Use when: you need to match pairs (brackets, tags), track nested state, or reverse order.
Check if a string of brackets is valid: every opening bracket must have a matching closing bracket in the correct order.
Use a slice as a stack.
Map closing brackets to their openers.
Push opening brackets onto the stack.
For closing brackets, check the stack top.
Pop: slice off the last element.
Valid only if all brackets were matched.
Trace: s = “([{}])”
’(’ -> push, stack: [(] ‘[’ -> push, stack: [(, [] ‘{’ -> push, stack: [(, [, {] ‘}’ -> top is ‘{’, match! pop, stack: [(, [] ‘]’ -> top is ‘[’, match! pop, stack: [(] ‘)’ -> top is ‘(’, match! pop, stack: [] stack empty -> valid!
func isValid(s string) bool {
var stack []byte
pairs := map[byte]byte{
')': '(',
']': '[',
'}': '{',
}
for i := 0; i < len(s); i++ {
ch := s[i]
if ch == '(' || ch == '[' || ch == '{' { stack = append(stack, ch)
} else { if len(stack) == 0 {
return false
}
top := stack[len(stack)-1]
if top != pairs[ch] {
return false
} stack = stack[:len(stack)-1]
}
}
return len(stack) == 0
}
func main() {
fmt.Println(isValid("([{}])"))
fmt.Println(isValid("([)]"))
fmt.Println(isValid("{[]}"))
fmt.Println(isValid("(("))
}