2.7 KiB
Leetcode Subarray-Sum-Equals-K
2022-09-05 15:22
Algorithms:
#algorithm #hash_table
Data structures:
#DS #array
Difficulty:
#coding_problems #difficulty_medium
Additional tags:
#leetcode #CS_list_need_practicing
Revisions:
N/A
Links:
Problem
Given an array of integers nums
and an integer k
, return the total number of subarrays whose sum equals to k
.
A subarray is a contiguous non-empty sequence of elements within an array.
Examples
Example 1:
Input: nums = [1,1,1], k = 2 Output: 2
Example 2:
Input: nums = [1,2,3], k = 3 Output: 2
Constraints
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
Thoughts
[!summary] This can be solved using #prefix_sum and #hash_table
I over-complicated the solution by adding stuff like sorting, but it turn out to be not so difficult.
Tip
Tried using sliding window, but it doesn't work because of negative numbers.
This one is harder to understand, making it a medium difficulty problem.
The intuition is using prefix to count the subarray sum, and use hashmaps to count the number of subarray sums. This takes care of negative numbers which is not solvable using sliding windows.
We step one cell at a time, and try to ask ourselves:
Can we hop back K to land on a cell?
And we answer this question by using hash maps and recording the data on the fly.
Solution
class Solution {
public:
int subarraySum(vector<int> &nums, int k) {
unordered_map<int, int> umap;
// sum == k is a solution, should be counted
umap[0] = 1;
int sum = 0;
int count = 0;
for (int i : nums) {
// update the prefix sum
sum += i;
if (umap.find(sum - k) != umap.end()) {
// we can land on a cell, then add the counter.
count += umap[sum - k];
}
// record this step.
umap[sum]++;
}
return count;
}
};
TLE, brute force
class Solution {
public:
int subarraySum(vector<int> &nums, int k) {
// O(N^2 / 2)
int n = nums.size();
if (n == 1) {
return (k == nums[0]);
}
vector<int> prefix(n + 1, 0);
int prefixSum = 0;
for (int i = 0; i < n; i++) {
prefixSum += nums[i];
prefix[i + 1] = prefixSum;
}
int count = 0;
for (int i = 0; i < n + 1; i++) {
for (int j = i + 1; j < n + 1; j++) {
if (prefix[j] - prefix[i] == k) {
count++;
}
}
}
return count;
}
};