medium array/string questions
This commit is contained in:
119
backend/data/questions/three-sum.yaml
Normal file
119
backend/data/questions/three-sum.yaml
Normal file
@@ -0,0 +1,119 @@
|
||||
title: 3Sum
|
||||
slug: three-sum
|
||||
difficulty: medium
|
||||
leetcode_id: 15
|
||||
leetcode_url: https://leetcode.com/problems/3sum/
|
||||
categories:
|
||||
- arrays
|
||||
- two-pointers
|
||||
- sorting
|
||||
patterns:
|
||||
- two-pointers
|
||||
|
||||
description: |
|
||||
Given an integer array `nums`, return all the triplets [nums[i], nums[j], nums[k]] such that
|
||||
i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
|
||||
|
||||
Notice that the solution set must not contain duplicate triplets.
|
||||
|
||||
constraints: |
|
||||
- 3 <= nums.length <= 3000
|
||||
- -10^5 <= nums[i] <= 10^5
|
||||
|
||||
examples:
|
||||
- input: "nums = [-1,0,1,2,-1,-4]"
|
||||
output: "[[-1,-1,2],[-1,0,1]]"
|
||||
explanation: "The distinct triplets that sum to zero."
|
||||
- input: "nums = [0,1,1]"
|
||||
output: "[]"
|
||||
explanation: "No triplet sums to zero."
|
||||
- input: "nums = [0,0,0]"
|
||||
output: "[[0,0,0]]"
|
||||
explanation: "Only one triplet sums to zero."
|
||||
|
||||
explanation:
|
||||
approach: |
|
||||
1. Sort the array
|
||||
2. For each element nums[i], find pairs that sum to -nums[i]
|
||||
3. Use two pointers (left, right) to find pairs in the remaining array
|
||||
4. Skip duplicates at each level to avoid duplicate triplets
|
||||
|
||||
intuition: |
|
||||
After sorting, for each fixed element nums[i], we need to find nums[j] + nums[k] = -nums[i].
|
||||
This reduces to the Two Sum II problem on a sorted array, solvable with two pointers.
|
||||
|
||||
Sorting enables two things: efficient two-pointer search and easy duplicate skipping.
|
||||
We skip duplicates by checking if current value equals previous value.
|
||||
|
||||
common_pitfalls:
|
||||
- title: Not handling duplicates
|
||||
description: |
|
||||
Without duplicate skipping, you'll return duplicate triplets.
|
||||
Skip at the outer loop and both pointers.
|
||||
wrong_approach: "Not skipping when nums[i] == nums[i-1]"
|
||||
correct_approach: "if i > 0 and nums[i] == nums[i-1]: continue"
|
||||
|
||||
- title: Wrong pointer skipping
|
||||
description: |
|
||||
After finding a valid triplet, skip duplicates for both left and right pointers
|
||||
while maintaining left < right.
|
||||
|
||||
- title: Starting i too late
|
||||
description: |
|
||||
The outer loop should start at index 0. Also, skip if nums[i] > 0 since
|
||||
sorted array means no valid triplet possible.
|
||||
|
||||
key_takeaways:
|
||||
- Reduce N-sum to (N-1)-sum by fixing one element
|
||||
- Sorting enables two-pointer approach and duplicate handling
|
||||
- Duplicate skipping happens at multiple levels
|
||||
- Time complexity is O(n²) — can't do better for returning all triplets
|
||||
|
||||
time_complexity: "O(n²)"
|
||||
space_complexity: "O(log n) to O(n)"
|
||||
complexity_explanation: |
|
||||
Time: O(n log n) for sorting + O(n²) for the two-pointer search.
|
||||
Space: Depends on sorting algorithm (log n for in-place, n for non-in-place).
|
||||
|
||||
solutions:
|
||||
- approach_name: Sort + Two Pointers (Optimal)
|
||||
is_optimal: true
|
||||
code: |
|
||||
def three_sum(nums: list[int]) -> list[list[int]]:
|
||||
nums.sort()
|
||||
result = []
|
||||
|
||||
for i in range(len(nums) - 2):
|
||||
# Skip duplicates for i
|
||||
if i > 0 and nums[i] == nums[i - 1]:
|
||||
continue
|
||||
|
||||
# Early termination
|
||||
if nums[i] > 0:
|
||||
break
|
||||
|
||||
left, right = i + 1, len(nums) - 1
|
||||
|
||||
while left < right:
|
||||
total = nums[i] + nums[left] + nums[right]
|
||||
|
||||
if total < 0:
|
||||
left += 1
|
||||
elif total > 0:
|
||||
right -= 1
|
||||
else:
|
||||
result.append([nums[i], nums[left], nums[right]])
|
||||
|
||||
# Skip duplicates for left and right
|
||||
while left < right and nums[left] == nums[left + 1]:
|
||||
left += 1
|
||||
while left < right and nums[right] == nums[right - 1]:
|
||||
right -= 1
|
||||
|
||||
left += 1
|
||||
right -= 1
|
||||
|
||||
return result
|
||||
explanation: |
|
||||
Fix one element and use two pointers to find the other two.
|
||||
Skip duplicates at all levels to avoid duplicate triplets.
|
||||
Reference in New Issue
Block a user