Add subarray sum equals K flashcards (LC 560, 974, 325)

This commit is contained in:
2026-05-26 01:15:40 +08:00
parent 3ab8ba001d
commit 978ab00faa
2 changed files with 183 additions and 0 deletions
+16
View File
@@ -81,3 +81,19 @@ public:
} }
}; };
#+end_src #+end_src
* TODO study: why min doesn't work with Fenwick tree (no inverse, update breaks on increase)
* Binary search
#+begin_src python
def bs(a, x, l, r):
if l >= r:
return l
m = l + (r-l) // 2
if (a[m] < x):
return bs(a, x, m+1, r);
else:
return bs(a, x, l, m)
#+end_src
+167
View File
@@ -0,0 +1,167 @@
#+title: Subarrays with Sum Equal to K
* Subarray Sum Equals K - Brute Force [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:LINK: https://leetcode.com/problems/subarray-sum-equals-k/description/
:END:
** Front
Find the total number of continuous subarrays whose sum equals k. Solve using the brute force approach.
Example: nums = [1,2,3], k = 3 → Output: 2 ([1,2] and [3])
** Back
#+begin_src c++
int subarraySum(vector<int>& nums, int k) {
int count = 0;
for (int i = 0; i < nums.size(); i++) {
int sum = 0;
for (int j = i; j < nums.size(); j++) {
sum += nums[j];
if (sum == k) count++;
}
}
return count;
}
#+end_src
Time: O(n^2), Space: O(1)
* Subarray Sum Equals K - Prefix Sum + Hash Map [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:LINK: https://leetcode.com/problems/subarray-sum-equals-k/description/
:END:
** Front
Find the total number of continuous subarrays whose sum equals k. Solve optimally using prefix sum with a hash map.
Example: nums = [1,2,3], k = 3 → Output: 2
** Back
#+begin_src c++
int subarraySum(vector<int>& nums, int k) {
unordered_map<int,int> prefixCount;
prefixCount[0] = 1; // base case: sum of 0 appears once
int sum = 0, count = 0;
for (int num : nums) {
sum += num;
// If (sum - k) exists, those prefixes form valid subarrays
count += prefixCount[sum - k];
prefixCount[sum]++;
}
return count;
}
#+end_src
Time: O(n), Space: O(n)
* Subarray Sum Equals K - Why prefixCount[0] = 1 [algorithm:interview]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:LINK: https://leetcode.com/problems/subarray-sum-equals-k/description/
:END:
** Front
In the optimal subarray sum solution (prefix sum + hash map), why is `prefixCount[0] = 1` initialized?
** Back
It handles the case where a subarray starts from index 0 and its sum equals k.
When sum == k at some index, we look up prefixCount[sum - k] = prefixCount[0].
Without the initialization, this lookup would return 0, missing valid subarrays like [3] where k = 3.
The base case means: "a prefix sum of 0 exists once (before any element)" — conceptually the empty prefix.
* Subarray Sum Divisible by K [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:LINK: https://leetcode.com/problems/subarray-sums-divisible-by-k/description/
:END:
** Front
Find the total number of continuous subarrays whose sum is divisible by k.
Example: nums = [23,2,4,6,7], k = 6 → Output: 2 ([2,4] and [7])
** Back
#+begin_src c++
int subarraysDivByK(vector<int>& nums, int k) {
unordered_map<int,int> prefixCount;
prefixCount[0] = 1;
int sum = 0, count = 0;
for (int num : nums) {
sum += num;
// Modulo can be negative in C++, fix with ((sum % k) + k) % k
int remainder = ((sum % k) + k) % k;
count += prefixCount[remainder];
prefixCount[remainder]++;
}
return count;
}
#+end_src
Key insight: If two prefix sums have the same remainder mod k, their subarray sum is divisible by k.
Time: O(n), Space: O(min(n, k))
* Longest Subarray Sum Equals K [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:LINK: https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/description/
:END:
** Front
Find the maximum length of a contiguous subarray that sums to k.
Example: nums = [1,-1,5,-2,3], k = 3 → Output: 4 ([1,-1,5,-2])
** Back
#+begin_src c++
int maxSubArrayLen(vector<int>& nums, int k) {
unordered_map<int,int> firstOccurrence;
firstOccurrence[0] = 0; // sum 0 at index 0 (1-based)
int sum = 0, maxLen = 0;
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
// Check if subarray ending here sums to k
if (firstOccurrence.count(sum - k)) {
maxLen = max(maxLen, i + 1 - firstOccurrence[sum - k]);
}
// Store first occurrence only (for longest)
if (!firstOccurrence.count(sum)) {
firstOccurrence[sum] = i + 1;
}
}
return maxLen;
}
#+end_src
Key difference from counting: store only the *first* occurrence of each prefix sum to maximize length.
Time: O(n), Space: O(n)
* Subarray Sum Equals K - Negative Numbers? [algorithm:interview]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:LINK: https://leetcode.com/problems/subarray-sum-equals-k/description/
:END:
** Front
Does the prefix sum + hash map approach for "subarray sum equals k" work when the array contains negative numbers? Why?
** Back
Yes, it works with negative numbers.
The prefix sum approach does NOT require positive-only elements. It works for any integer array because:
- prefix[j] - prefix[i] = sum[i+1..j] is always true regardless of sign
- The hash map tracks ALL prefix sums seen, positive or negative
- We only need (sum - k) to exist in the map
This makes it superior to the sliding window approach, which only works for non-negative arrays.
* Subarray Sum Equals K - Sliding Window Limitation [algorithm:interview]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:LINK: https://leetcode.com/problems/subarray-sum-equals-k/description/
:END:
** Front
Can you use the sliding window technique to solve "subarray sum equals k"? When does it work?
** Back
Sliding window ONLY works when all elements are non-negative (positive or zero).
When all elements >= 0:
- Expanding the window increases the sum
- Shrinking the window decreases the sum
- This monotonicity lets us adjust the window
Sliding window fails with negative numbers because adding/removing elements doesn't monotonically change the sum.
Prefer prefix sum + hash map — it works for all cases (positive, negative, zero).