mirror of
https://github.com/prdlk/leetcode.git
synced 2026-11-02 13:12:44 +00:00
docs(docs): add and expand algorithm documentation
This commit is contained in:
1 parent
34bb305a96
commit
32a41bdcb0
10 files changed
+1061
-50
No files matched your search
@@ -3,7 +3,117 @@ title: 'Prefix Sum'
|
||||
description: 'Precomputed cumulative state for O(1) range queries.'
|
||||
---
|
||||
|
||||
:::warning[Under construction]
|
||||
This page is a scaffold. Notes, canonical problems, and template code are not written yet.
|
||||
:::
|
||||
## The idea
|
||||
|
||||
Precompute running totals once. Then any range sum costs O(1).
|
||||
|
||||
Like mile markers on a highway.
|
||||
Distance from mile 30 to mile 80? Subtract: 80 − 30 = 50.
|
||||
You do not re-drive the road.
|
||||
|
||||
**The formula:** `sum(i..j) = prefix[j + 1] - prefix[i]`
|
||||
|
||||
## The picture
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["nums: 3 1 4 1 5"] --> B["prefix: 0 3 4 8 9 14"]
|
||||
B --> C["sum(1..3) = prefix[4] − prefix[1]<br/>= 9 − 3 = 6"]
|
||||
C --> D["Check: 1 + 4 + 1 = 6 ✓"]
|
||||
|
||||
style D fill:#2e7d32,color:#fff
|
||||
```
|
||||
|
||||
The leading 0 matters. It makes ranges that start at index 0 work with no special case.
|
||||
|
||||
## Range Sum Query (LC 303)
|
||||
|
||||
Pay O(n) once at build time. Answer every query in O(1).
|
||||
|
||||
```python
|
||||
from itertools import accumulate
|
||||
|
||||
class NumArray:
|
||||
def __init__(self, nums: list[int]):
|
||||
self.prefix = [0] + list(accumulate(nums))
|
||||
|
||||
def sum_range(self, left: int, right: int) -> int:
|
||||
return self.prefix[right + 1] - self.prefix[left]
|
||||
```
|
||||
|
||||
## Prefix + Hashmap (LC 560 — Subarray Sum Equals K)
|
||||
|
||||
The signature trick of this topic. The question flips:
|
||||
"Which subarrays sum to k?" becomes
|
||||
"At each point, how many *earlier* prefixes equal `current − k`?"
|
||||
|
||||
Because: if `prefix[j] − prefix[i] = k`, the slice between them sums to k.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Walk the array,<br/>carry running sum"] --> B["Ask the map:<br/>seen sum − k before?"]
|
||||
B --> C["Yes, m times →<br/>add m to answer"]
|
||||
B --> D["Record current sum<br/>in the map"]
|
||||
D --> A
|
||||
|
||||
style C fill:#2e7d32,color:#fff
|
||||
```
|
||||
|
||||
```python
|
||||
from collections import defaultdict
|
||||
|
||||
def subarray_sum(nums: list[int], k: int) -> int:
|
||||
count = 0
|
||||
current = 0
|
||||
seen = defaultdict(int)
|
||||
seen[0] = 1 # empty prefix — subarrays that start at 0
|
||||
|
||||
for n in nums:
|
||||
current += n
|
||||
count += seen[current - k] # ask first
|
||||
seen[current] += 1 # record after
|
||||
return count
|
||||
```
|
||||
|
||||
**Order matters.** Ask before you record, or a subarray of length 0 counts itself when k = 0.
|
||||
|
||||
## Product variant (LC 238 — Product of Array Except Self)
|
||||
|
||||
Same idea, two directions. Prefix products from the left, suffix products from the right.
|
||||
`answer[i] = left[i] × right[i]` — everything except i.
|
||||
|
||||
```python
|
||||
def product_except_self(nums: list[int]) -> list[int]:
|
||||
n = len(nums)
|
||||
result = [1] * n
|
||||
|
||||
left = 1
|
||||
for i in range(n):
|
||||
result[i] = left
|
||||
left *= nums[i]
|
||||
|
||||
right = 1
|
||||
for i in range(n - 1, -1, -1):
|
||||
result[i] *= right
|
||||
right *= nums[i]
|
||||
return result
|
||||
```
|
||||
|
||||
## Complexity
|
||||
|
||||
| | Time | Space |
|
||||
|---|---|---|
|
||||
| Build | O(n) | O(n) |
|
||||
| Each range query | O(1) | — |
|
||||
| Prefix + hashmap | O(n) one pass | O(n) |
|
||||
|
||||
## Close-out ritual
|
||||
|
||||
Before you submit, say out loud:
|
||||
1. Time and space complexity.
|
||||
2. One edge case trace: range starting at 0, k = 0 with zeros in the array, or negative numbers (this is why sliding window fails and prefix + hashmap wins).
|
||||
|
||||
## Plan problems
|
||||
|
||||
**A-set:** LC 303 · 238 · 560
|
||||
**B-set:** LC 525 · 974
|
||||
Reference in new issue
Block a user