Range Sum Query
📘 Problem Statement
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.
🔍 Example
Example 1:
Input: nums = [1,1,1], k = 2
Output: 2
Example 2:
Input: nums = [1,2,3], k = 3
Output: 2
🛠️ Solution
❌ Brute Force Approach (Inefficient)
Try every possible subarray and check if its sum is k
.
Code
def subarray_sum_equals_k(nums, k):
count = 0
for i in range(len(nums)):
sum_ = 0
for j in range(i, len(nums)):
sum_ += nums[j]
if sum_ == k:
count += 1
⏱️ Time Complexity:
\(O(n^2)\) — not scalable for large arrays.
⚡ Optimized Approach:
🔑 Key Idea:
Let:
nums
be the input array of integersk
be the targetsum
then, prefix_sum[i]
is the sum of the first i elements.
Our goal is to count the number of subarrays nums[i..j]
such that:
This is equivalent to finding the number of pairs (i,j)
such that :
Rearranging,
\[\large prefix\_sum[j] - k =prefix\_sum[i-1]\]This tells us, at each index j
, if there exists an earlier prefix sum prefix_sum[i - 1]
such that:
then the subarray from i
to j
sums to k
.
✅ Why It Works
This approach efficiently counts all previous prefix_sum values that could start a valid subarray ending at the current index. Each valid match contributes to the total number of subarrays that sum to k
.
def subarraySum(self, nums: List[int], k: int) -> int:
# dictionary which keeps track of count of all prefix sum.
d = {0: 1} # Initialize with sum 0 having one count. Base case.
subarray_count = 0
# accumulate prefix_sum
sum_so_far = 0
for ix,num in enumerate(nums):
#prefix sum so far
sum_so_far += num
find_prev_prefix = sum_so_far - k
# subarray so far
subarray_count += d.get(find_prev_prefix, 0)
d[sum_so_far] = d.get(sum_so_far, 0) + 1
return subarray_count
⏱️ Time & Space Complexity
Operation | Complexity |
---|---|
Time | \(O(n)\) |
Space | \(O(n)\) |