Add subarray sum equals K flashcards (LC 560, 974, 325)
This commit is contained in:
@@ -81,3 +81,19 @@ public:
|
||||
}
|
||||
};
|
||||
#+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
|
||||
|
||||
@@ -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).
|
||||
Reference in New Issue
Block a user