feat(content): initial question set
This commit is contained in:
117
backend/data/questions/two-sum.yaml
Normal file
117
backend/data/questions/two-sum.yaml
Normal file
@@ -0,0 +1,117 @@
|
||||
title: Two Sum
|
||||
slug: two-sum
|
||||
difficulty: easy
|
||||
leetcode_id: 1
|
||||
leetcode_url: https://leetcode.com/problems/two-sum/
|
||||
categories:
|
||||
- arrays
|
||||
- hash-tables
|
||||
patterns:
|
||||
- two-pointers
|
||||
|
||||
description: |
|
||||
Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.
|
||||
|
||||
You may assume that each input would have exactly one solution, and you may not use the same element twice.
|
||||
|
||||
You can return the answer in any order.
|
||||
|
||||
constraints: |
|
||||
- 2 <= nums.length <= 10^4
|
||||
- -10^9 <= nums[i] <= 10^9
|
||||
- -10^9 <= target <= 10^9
|
||||
- Only one valid answer exists.
|
||||
|
||||
examples:
|
||||
- input: "nums = [2,7,11,15], target = 9"
|
||||
output: "[0,1]"
|
||||
explanation: "Because nums[0] + nums[1] == 9, we return [0, 1]."
|
||||
- input: "nums = [3,2,4], target = 6"
|
||||
output: "[1,2]"
|
||||
explanation: "Because nums[1] + nums[2] == 6, we return [1, 2]."
|
||||
- input: "nums = [3,3], target = 6"
|
||||
output: "[0,1]"
|
||||
explanation: "Because nums[0] + nums[1] == 6, we return [0, 1]."
|
||||
|
||||
explanation:
|
||||
approach: |
|
||||
1. Create a hash map to store each number and its index as we iterate
|
||||
2. For each number, calculate its complement (target - current number)
|
||||
3. Check if the complement exists in the hash map
|
||||
4. If found, return the current index and the complement's index
|
||||
5. If not found, add the current number and its index to the hash map
|
||||
6. Continue until a pair is found
|
||||
|
||||
intuition: |
|
||||
The brute force approach would check every pair of numbers, resulting in O(n²) time.
|
||||
Instead, we can use a hash map to achieve O(n) time by trading space for speed.
|
||||
|
||||
The key insight is that for each number x, we're looking for (target - x). Rather than
|
||||
scanning the entire array each time, we store seen numbers in a hash map for O(1) lookup.
|
||||
|
||||
We build the hash map as we go, which elegantly handles the constraint of not using
|
||||
the same element twice — when we check for a complement, it can only be a previously
|
||||
seen element.
|
||||
|
||||
common_pitfalls:
|
||||
- title: Using the same element twice
|
||||
description: |
|
||||
Checking if complement exists before adding current element to the map prevents
|
||||
using the same index twice. If you add first then check, you might match an
|
||||
element with itself.
|
||||
wrong_approach: "Adding to map before checking complement"
|
||||
correct_approach: "Check complement first, then add to map"
|
||||
|
||||
- title: Returning values instead of indices
|
||||
description: |
|
||||
The problem asks for indices, not the actual values. Make sure you store and
|
||||
return the indices from the hash map.
|
||||
wrong_approach: "return [num, complement]"
|
||||
correct_approach: "return [seen[complement], i]"
|
||||
|
||||
- title: Forgetting duplicate values
|
||||
description: |
|
||||
When there are duplicate values (e.g., [3,3] with target 6), the algorithm
|
||||
still works because we check for complement before adding to the map.
|
||||
|
||||
key_takeaways:
|
||||
- Hash maps trade space for time, turning O(n) lookups into O(1)
|
||||
- Building data structures incrementally can prevent edge cases
|
||||
- Always clarify whether to return indices or values
|
||||
- This pattern appears in many "find pair" problems
|
||||
|
||||
time_complexity: "O(n)"
|
||||
space_complexity: "O(n)"
|
||||
complexity_explanation: |
|
||||
Time: We iterate through the array once, and each hash map operation is O(1) average.
|
||||
Space: In the worst case, we store all n elements in the hash map before finding a match.
|
||||
|
||||
solutions:
|
||||
- approach_name: Hash Map (Optimal)
|
||||
is_optimal: true
|
||||
code: |
|
||||
def two_sum(nums: list[int], target: int) -> list[int]:
|
||||
seen = {}
|
||||
for i, num in enumerate(nums):
|
||||
complement = target - num
|
||||
if complement in seen:
|
||||
return [seen[complement], i]
|
||||
seen[num] = i
|
||||
return [] # No solution found
|
||||
explanation: |
|
||||
Single pass through the array, storing each number's index.
|
||||
For each number, check if its complement exists in the map.
|
||||
|
||||
- approach_name: Brute Force
|
||||
is_optimal: false
|
||||
code: |
|
||||
def two_sum(nums: list[int], target: int) -> list[int]:
|
||||
n = len(nums)
|
||||
for i in range(n):
|
||||
for j in range(i + 1, n):
|
||||
if nums[i] + nums[j] == target:
|
||||
return [i, j]
|
||||
return []
|
||||
explanation: |
|
||||
Check every pair of numbers. Simple but inefficient for large inputs.
|
||||
Time: O(n²), Space: O(1).
|
||||
Reference in New Issue
Block a user