mirror of
https://github.com/prdlk/leetcode.git
synced 2026-11-02 13:12:44 +00:00
docs(content): enhance linear-structures docs with detailed explanations, new problem page, updated images, and corrected array badge count
This commit is contained in:
1 parent
fdd54e4a1c
commit
16317c8645
5 files changed
+141
-5
No files matched your search
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: '974. Subarray Sums Divisible by K'
|
||||
description: Given an integer array nums and an integer k, return the number of non-empty subarrays that have a sum divisible by k
|
||||
icon: dot
|
||||
topics:
|
||||
- { name: "Array", slug: "array" }
|
||||
- { name: "Hash Table", slug: "hash-table" }
|
||||
- { name: "Prefix Sum", slug: "prefix-sum" }
|
||||
issue: "https://github.com/prdlk/leetcode/issues/40"
|
||||
sidebar:
|
||||
label: 'Subarray Sums Divisible by K'
|
||||
badge: 'Medium'
|
||||
---
|
||||
|
||||
### Example 1:
|
||||
- Input: `nums = [4,5,0,-2,-3,1], k = 5`
|
||||
- Output: `7`
|
||||
- Explanation: There are `7` subarrays with a sum divisible by `k = 5`: [4, `5`, `0`, `-2`, `-3`, 1], `[5]`, [5, 0], [5, `0`, `-2`, -3], `[0]`, [0, `-2`, -3], [-2, -3]
|
||||
|
||||
### Example 2:
|
||||
- Input: `nums = [5], k = 9`
|
||||
- Output: `0`
|
||||
|
||||
### Constraints:
|
||||
|
||||
- `1 <= nums.length <= 3 * 10^4`
|
||||
- `-10^4 <= nums[i] <= 10^4`
|
||||
- `2 <= k <= 10^4`
|
||||
|
||||
## Solution
|
||||
|
||||
```py
|
||||
class Solution:
|
||||
def subarraysDivByK(self, nums: list[int], k: int) -> int:
|
||||
remainder_counts = {0: 1}
|
||||
cur_sum = 0
|
||||
count = 0
|
||||
|
||||
for n in nums:
|
||||
cur_sum += n
|
||||
remainder = cur_sum % k
|
||||
|
||||
if remainder in remainder_counts:
|
||||
count += remainder_counts[remainder]
|
||||
|
||||
remainder_counts[remainder] = remainder_counts.get(remainder, 0) + 1
|
||||
|
||||
return count
|
||||
```
|
||||
@@ -3,3 +3,40 @@ title: Prefix Sum
|
||||
description: 'A running total is stored at each index, so the sum of any range is one subtraction.'
|
||||
hidden: true
|
||||
---
|
||||
|
||||
Suppose you are handed an array and asked for the sum of the elements between index `i` and index `j`. One query is easy: loop from `i` to `j` and add. But now imagine thousands of such queries over the same array, or a search that inspects the sum of every possible subarray. Recomputing each range from scratch costs `O(n)` per query, and the work piles up fast.
|
||||
|
||||
Prefix sum removes that repetition. You spend `O(n)` once to precompute running totals, and afterward every range sum collapses into a single subtraction that runs in `O(1)`, no matter how wide the range.
|
||||
|
||||
<YouTube id="CRVxUgmIO8M" title="Prefix Sum Explained" />
|
||||
|
||||
## Transformation
|
||||
|
||||
A prefix sum turns an array into a new array of running totals. For an input array `arr` of length `n`, build a `prefix` array of length `n + 1`:
|
||||
|
||||
`prefix[0] = 0`
|
||||
|
||||
`prefix[k] = arr[0] + arr[1] + ... + arr[k-1]`
|
||||
|
||||
Each entry is the previous total plus one more element, so a single pass builds the whole thing:
|
||||
|
||||
`prefix[k] = prefix[k-1] + arr[k-1]`
|
||||
|
||||
The leading `prefix[0] = 0` is the sum of zero elements. That extra slot is what makes the range math below land exactly on the boundaries, which is why `prefix` has one more cell than `arr`.
|
||||
|
||||
|
||||
<Frame caption="Each bar is the running total up to that index. Every step keeps the previous total (blue) and adds one new element (amber)" hint="">
|
||||
<img src="../../../public/prefix-sum_1.png" alt="" />
|
||||
</Frame>
|
||||
|
||||
## Any range sum is one subtraction
|
||||
|
||||
The sum of the subarray from index `i` up to (but not including) `j` is `prefix[j] - prefix[i]`. `prefix[j]` is the total of everything before `j`, and `prefix[i]` is the total of everything before `i`, so subtracting throws away the front you did not ask for and leaves the middle.
|
||||
|
||||
## Watch the boundaries
|
||||
|
||||
The one place prefix sums trip people up is the off-by-one at the edges. Keep three facts straight: `prefix` has length `n + 1`, `prefix[0]` is `0`, and `sum(arr[i..j-1]) = prefix[j] - prefix[i]` uses an exclusive right index `j`. If a problem hands you an inclusive right index `r`, translate it to `prefix[r + 1] - prefix[i]`.
|
||||
|
||||
## When to reach for it
|
||||
|
||||
Prefix sums fit whenever you need repeated range sums over a fixed array, or when an algorithm searches across subarray boundaries. For a single one-off sum, a plain loop is simpler; the prefix array earns its `O(n)` setup only once the same array is queried many times.
|
||||
Reference in new issue
Block a user