feat(content): initial question set

This commit is contained in:
2025-04-21 21:17:13 +01:00
parent e4a71ade59
commit b4110d6abd
3 changed files with 395 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
title: Valid Parentheses
slug: valid-parentheses
difficulty: easy
leetcode_id: 20
leetcode_url: https://leetcode.com/problems/valid-parentheses/
categories:
- strings
- stack
patterns:
- monotonic-stack
description: |
Given a string `s` containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.
An input string is valid if:
1. Open brackets must be closed by the same type of brackets.
2. Open brackets must be closed in the correct order.
3. Every close bracket has a corresponding open bracket of the same type.
constraints: |
- 1 <= s.length <= 10^4
- s consists of parentheses only '()[]{}'
examples:
- input: 's = "()"'
output: "true"
explanation: "Single pair of matching parentheses."
- input: 's = "()[]{}"'
output: "true"
explanation: "Three separate valid pairs."
- input: 's = "(]"'
output: "false"
explanation: "Mismatched bracket types."
- input: 's = "([)]"'
output: "false"
explanation: "Incorrect nesting order."
explanation:
approach: |
1. Create a mapping of closing brackets to their opening counterparts
2. Initialize an empty stack to track opening brackets
3. Iterate through each character in the string:
- If it's an opening bracket, push it onto the stack
- If it's a closing bracket, check if the stack is empty (invalid) or if the top
of the stack matches the corresponding opening bracket
4. After processing all characters, the stack should be empty for a valid string
intuition: |
The key insight is that brackets must be closed in LIFO (Last-In-First-Out) order.
The most recently opened bracket must be closed first, which is exactly what a stack does.
When we encounter a closing bracket, the most recent unclosed opening bracket (top of stack)
must match it. If they don't match, or if there's no opening bracket to match, the string
is invalid.
Think of it like nested function calls — the innermost function must return before the
outer one can.
common_pitfalls:
- title: Forgetting to check empty stack
description: |
When encountering a closing bracket, you must first check if the stack is empty.
If it is, there's no matching opening bracket.
wrong_approach: "Directly checking stack[-1] without empty check"
correct_approach: "Check if stack is empty before accessing stack[-1]"
- title: Not checking if stack is empty at the end
description: |
After processing all characters, leftover opening brackets in the stack mean
they were never closed. Return stack is empty, not just True.
wrong_approach: "return True after the loop"
correct_approach: "return len(stack) == 0"
- title: Confusing bracket mapping direction
description: |
Map closing brackets to opening brackets (not vice versa) because we encounter
closing brackets when we need to check for a match.
key_takeaways:
- Stacks are ideal for matching nested structures
- LIFO order matches the nesting requirement of brackets
- Always check edge cases (empty string, only opening, only closing)
- This pattern extends to validating HTML tags, code blocks, etc.
time_complexity: "O(n)"
space_complexity: "O(n)"
complexity_explanation: |
Time: We process each character exactly once.
Space: In the worst case (all opening brackets), the stack holds n/2 elements.
solutions:
- approach_name: Stack (Optimal)
is_optimal: true
code: |
def is_valid(s: str) -> bool:
stack = []
mapping = {')': '(', '}': '{', ']': '['}
for char in s:
if char in mapping:
# Closing bracket
if not stack or stack[-1] != mapping[char]:
return False
stack.pop()
else:
# Opening bracket
stack.append(char)
return len(stack) == 0
explanation: |
Use a stack to track opening brackets. For each closing bracket,
verify it matches the most recent opening bracket.
- approach_name: Stack with Early Return
is_optimal: true
code: |
def is_valid(s: str) -> bool:
# Quick check: odd length can never be valid
if len(s) % 2 != 0:
return False
stack = []
pairs = {'(': ')', '{': '}', '[': ']'}
for char in s:
if char in pairs:
stack.append(pairs[char])
elif not stack or stack.pop() != char:
return False
return not stack
explanation: |
Optimization: push the expected closing bracket instead of the opening one.
This simplifies the comparison when we encounter a closing bracket.