Convert LeetCode links to org-mode inline format

This commit is contained in:
2026-05-26 01:19:43 +08:00
parent 978ab00faa
commit defa2145e8
+346 -14
View File
@@ -2,10 +2,9 @@
* 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.
See [[https://leetcode.com/problems/subarray-sum-equals-k/description/][LC 560]]. 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
@@ -27,10 +26,9 @@ 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.
See [[https://leetcode.com/problems/subarray-sum-equals-k/description/][LC 560]]. 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
@@ -53,10 +51,9 @@ 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?
See [[https://leetcode.com/problems/subarray-sum-equals-k/description/][LC 560]]. 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.
@@ -69,10 +66,9 @@ The base case means: "a prefix sum of 0 exists once (before any element)" — co
* 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.
See [[https://leetcode.com/problems/subarray-sums-divisible-by-k/description/][LC 974]]. 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
@@ -98,10 +94,9 @@ 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.
See [[https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/description/][LC 325]]. 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
@@ -131,10 +126,9 @@ 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?
See [[https://leetcode.com/problems/subarray-sum-equals-k/description/][LC 560]]. 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.
@@ -149,10 +143,9 @@ This makes it superior to the sliding window approach, which only works for non-
* 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?
See [[https://leetcode.com/problems/subarray-sum-equals-k/description/][LC 560]]. 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).
@@ -165,3 +158,342 @@ When all elements >= 0:
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).
* Subarray Sum Variations — Master Table [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
What's the master table of subarray sum variations and their approaches?
** Back
| Question | Constraint | Approach | Key Data Structure | Time |
|----------|-----------|----------|-------------------|------|
| Count subarrays sum = K | Any integers | Prefix sum | unordered_map<sum, frequency> | O(n) |
| Longest subarray sum = K | Any integers | Prefix sum | unordered_map<sum, first_index> | O(n) |
| Shortest subarray sum ≥ K | Any integers | Prefix sum + monotonic deque | deque of indices | O(n) |
| Shortest subarray sum = K | Any integers | Prefix sum + ordered map | map<sum, last_index> | O(n log n) |
| Divisible by K | Any integers | Prefix sum + modulo | unordered_map<remainder, freq> | O(n) |
| Sum in range [lower, upper] | Any integers | Prefix sum + BST | multiset / Fenwick / segment tree | O(n log n) |
| Max circular subarray sum | Any integers | Kadane's + total - min_subarray | 2x Kadane | O(n) |
| Subarray sum with only positives | Positives only | Sliding window | Two pointers | O(n) |
| 2D matrix subarray sum = K | 2D grid | Fix rows, compress to 1D | Prefix sum on compressed row | O(n^3) |
| At most K distinct elements | Frequency constraint | Sliding window + freq map | Hash map of counts | O(n) |
| Subarray with exactly K ones | Binary array | Store indices of 1s | Vector of positions | O(n) |
| Two non-overlapping subarrays each = K | Any integers | Prefix sum + track both sides | 2 pass with prefix map | O(n) |
Core pattern: prefix[j] - prefix[i] = subarray(i+1..j). The variation changes what you store and query.
* Subarray Shortest Sum ≥ K — Monotonic Deque [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
See [[https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/description/][LC 862]]. Find the length of the shortest contiguous subarray with sum ≥ K. Works with negative numbers.
Example: nums = [84,-37,32,40,95], K = 167 → Output: 3
** Back
#+begin_src c++
int shortestSubarray(vector<int>& nums, int k) {
int n = nums.size();
vector<long long> prefix(n + 1, 0);
for (int i = 0; i < n; i++) prefix[i + 1] = prefix[i] + nums[i];
deque<int> dq; // stores indices, prefix[dq[j]] is increasing
int minLen = INT_MAX;
for (int i = 0; i <= n; i++) {
// If prefix[i] - prefix[dq.front()] >= K, pop front and record length
while (!dq.empty() && prefix[i] - prefix[dq.front()] >= k) {
minLen = min(minLen, i - dq.front());
dq.pop_front();
}
// Maintain monotonic increasing order of prefix values in deque
while (!dq.empty() && prefix[i] < prefix[dq.back()]) {
dq.pop_back();
}
dq.push_back(i);
}
return minLen == INT_MAX ? -1 : minLen;
}
#+end_src
Time: O(n), Space: O(n)
Key insight: Maintain a deque of indices where prefix sums are increasing.
If prefix[i] - prefix[dq.front()] ≥ K, then any index after dq.front() gives a shorter valid subarray.
* Subarray Sum in Range [lower, upper] [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
See [[https://leetcode.com/problems/count-of-range-sum/description/][LC 327]]. Count the number of subarrays whose sum lies in range [lower, upper].
Example: nums = [-2,5,-1], lower = -2, upper = 2 → Output: 3 ([-2], [-1], [5,-1])
** Back
#+begin_src c++
int countRangeSum(vector<int>& nums, int lower, int upper) {
int n = nums.size();
vector<long long> prefix(n + 1, 0);
for (int i = 0; i < n; i++) prefix[i + 1] = prefix[i] + nums[i];
// Use merge sort to count valid pairs
return mergeCount(prefix, 0, n, lower, upper);
}
int mergeCount(vector<long long>& P, int lo, int hi, int lower, int upper) {
if (lo >= hi - 1) return 0;
int mid = lo + (hi - lo) / 2;
int count = mergeCount(P, lo, mid, lower, upper)
+ mergeCount(P, mid, hi, lower, upper);
// Count valid (i, j) pairs where P[j] - P[i] in [lower, upper]
int j = mid, k = mid, t = mid;
for (int i = lo; i < mid; i++) {
while (k <= hi && P[k] - P[i] < lower) k++;
while (t <= hi && P[t] - P[i] <= upper) t++;
count += (t - k);
}
// Merge step
vector<long long> temp;
int p1 = lo, p2 = mid;
while (p1 < mid && p2 < hi) {
if (P[p1] <= P[p2]) temp.push_back(P[p1++]);
else temp.push_back(P[p2++]);
}
while (p1 < mid) temp.push_back(P[p1++]);
while (p2 < hi) temp.push_back(P[p2++]);
for (int i = 0; i < (int)temp.size(); i++) P[lo + i] = temp[i];
return count;
}
#+end_src
Time: O(n log n), Space: O(n)
Why not hash map? Hash map can't count how many prefix sums fall in a range.
Merge sort counts (i, j) pairs where P[j] - P[i] ∈ [lower, upper] during the merge step.
* Max Circular Subarray Sum [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
See [[https://leetcode.com/problems/maximum-sum-circular-subarray/description/][LC 918]]. Find the maximum sum of a non-empty subarray in a circular array.
Example: nums = [1,-2,3,-2] → Output: 3
Example: nums = [5,-3,5] → Output: 10 (wraps around: [5, 5])
** Back
#+begin_src c++
int maxSubarraySumCircular(vector<int>& nums) {
int total = 0, maxSum = nums[0], curMax = 0;
int minSum = nums[0], curMin = 0;
for (int num : nums) {
curMax = max(curMax + num, num);
maxSum = max(maxSum, curMax);
curMin = min(curMin + num, num);
minSum = min(minSum, curMin);
total += num;
}
// If all numbers are negative, maxSum is the answer (total - minSum = 0)
return maxSum < 0 ? maxSum : max(maxSum, total - minSum);
}
#+end_src
Time: O(n), Space: O(1)
Two cases:
1. Maximum subarray does NOT wrap — standard Kadane's (maxSum)
2. Maximum subarray DOES wrap — total - minSubarray (remove the minimum subarray from the middle)
Edge case: all negative → total - minSum = 0, which is wrong. Return maxSum instead.
* 2D Matrix Subarray Sum = K [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
See [[https://leetcode.com/problems/number-of-submatrices-that-sum-to-target/description/][Submatrices Sum to Target]]. Given a 2D matrix, find the number of submatrices whose sum equals K.
Example: matrix = [[0,1,0],[1,1,1],[0,1,0]], K = 0 → Output: 4
** Back
#+begin_src c++
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
int m = matrix.size(), n = matrix[0].size();
int count = 0;
// Fix top and bottom rows, compress to 1D array
for (int r1 = 0; r1 < m; r1++) {
vector<int> colSum(n, 0);
for (int r2 = r1; r2 < m; r2++) {
// Add row r2 to the compressed column sums
for (int c = 0; c < n; c++) {
colSum[c] += matrix[r2][c];
}
// Now solve 1D subarray sum = target
unordered_map<int,int> prefixCount;
prefixCount[0] = 1;
int sum = 0;
for (int val : colSum) {
sum += val;
count += prefixCount[sum - target];
prefixCount[sum]++;
}
}
}
return count;
}
#+end_src
Time: O(m^2 * n), Space: O(n)
Key idea: Fix two rows (r1, r2), compress columns between them into a 1D array.
Then the problem reduces to 1D subarray sum = K.
* Exactly K Distinct Elements with Sum = K [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
Find the length of the longest subarray with at most K distinct elements and sum = K.
** Back
#+begin_src c++
int longestSubarray(vector<int>& nums, int k) {
unordered_map<int,int> freq;
int sum = 0, distinct = 0, maxLen = 0;
int left = 0;
for (int right = 0; right < nums.size(); right++) {
if (freq[nums[right]] == 0) distinct++;
freq[nums[right]]++;
sum += nums[right];
// Shrink while distinct > K or sum > k
while (distinct > k || sum > k) {
freq[nums[left]]--;
if (freq[nums[left]] == 0) distinct--;
sum -= nums[left];
left++;
}
if (sum == k) maxLen = max(maxLen, right - left + 1);
}
return maxLen;
}
#+end_src
Time: O(n), Space: O(min(n, K))
This combines sliding window (distinct elements constraint) with sum check.
The two constraints (distinct count + sum) make it trickier than simple sliding window.
* Binary Array — Exactly K Ones [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
See [[https://leetcode.com/problems/max-consecutive-ones-iii/description/][LC 1004]]. Given a binary array nums and an integer k, return the maximum number of consecutive 1's in the array if you can flip at most k 0's.
Example: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2 → Output: 6
** Back
#+begin_src c++
int longestOnes(vector<int>& nums, int k) {
int left = 0, maxLen = 0;
for (int right = 0; right < nums.size(); right++) {
if (nums[right] == 0) k--;
while (k < 0) {
if (nums[left] == 0) k++;
left++;
}
maxLen = max(maxLen, right - left + 1);
}
return maxLen;
}
#+end_src
Time: O(n), Space: O(1)
Sliding window: expand right, count zeros. When zeros exceed k, shrink from left.
* Two Non-Overlapping Subarrays Each Sum = K [algorithm:array]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
Find the maximum sum of two non-overlapping subarrays with lengths L and M.
Example: nums = [0,6,5,2,2,5,1,9,4], L = 1, M = 2 → Output: 20 ([9] and [6,5])
** Back
#+begin_src c++
int maxSumTwoNoOverlap(vector<int>& nums, int L, int M) {
int n = nums.size();
// Prefix sums for O(1) subarray sum queries
vector<int> prefix(n + 1, 0);
for (int i = 0; i < n; i++) prefix[i + 1] = prefix[i] + nums[i];
auto sum = [&](int i, int j) { return prefix[j + 1] - prefix[i]; };
int maxL = 0, maxM = 0, result = 0;
// Case 1: L comes before M
for (int i = L + M; i <= n; i++) {
maxL = max(maxL, sum(i - L - M, i - M - 1));
maxM = max(maxM, sum(i - M, i - 1));
result = max(result, maxL + maxM);
}
// Case 2: M comes before L
maxL = 0; maxM = 0; result = 0;
for (int i = L + M; i <= n; i++) {
maxM = max(maxM, sum(i - L - M, i - L - 1));
maxL = max(maxL, sum(i - L, i - 1));
result = max(result, maxL + maxM);
}
return result;
}
#+end_src
Time: O(n), Space: O(n)
Two cases: L before M, or M before L.
Track the running maximum of the first subarray while computing the second.
* Subarray Sum — All Relationships Diagram [algorithm:interview]
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
:END:
** Front
What's the decision tree for choosing the right subarray sum approach?
** Back
1. **Are there negative numbers?**
→ YES: Prefix sum approach (hash map, BST, or merge sort)
→ NO: Sliding window is possible
2. **What are you counting?**
→ Count all: hash_map<sum, frequency>
→ Longest: hash_map<sum, first_index>
→ Shortest: hash_map<sum, last_index> or monotonic deque
3. **Is the target a range [lower, upper]?**
→ YES: Merge sort (count pairs in range) or Fenwick tree / BST
4. **Is it divisible by K?**
→ YES: hash_map<remainder, frequency> with modulo
5. **Is the array circular?**
→ YES: Kadane's twice — max(max_subarray, total - min_subarray)
6. **Is it 2D?**
→ YES: Fix 2 rows, compress to 1D, then prefix sum
7. **Are elements only 0/1?**
→ YES: Store indices of 1s, or sliding window counting zeros
8. **Are there constraints on distinct elements?**
→ YES: Sliding window + frequency map
9. **Are there multiple non-overlapping subarrays?**
→ YES: 2-pass — track running max of first while computing second
The fundamental identity: subarray(i,j) = prefix[j+1] - prefix[i].
Everything else is about what you do with the prefix array.