Given an integer array nums
and an integer k
, return the number of non-empty subarrays that have a sum divisible by k
.
A subarray is a contiguous part of an array.
Example 1:
Input: nums = [4,5,0,-2,-3,1], k = 5 Output: 7 Explanation: There are 7 subarrays with a sum divisible by k = 5: [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
Example 2:
Input: nums = [5], k = 9 Output: 0
Constraints:
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
2 <= k <= 104
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To solve this problem the brute force way, we'll check every possible group of numbers in the list. We'll calculate the sum of each group and see if that sum is evenly divisible by our target number.
Here's how the algorithm would work step-by-step:
def subarray_sums_divisible_by_k_brute_force(number_list, target):
count_divisible_subarrays = 0
for start_index in range(len(number_list)):
current_subarray_sum = 0
# Iterate through all subarrays starting
# from the current start_index.
for end_index in range(start_index, len(number_list)):
current_subarray_sum += number_list[end_index]
# Check divisibility after summing.
if current_subarray_sum % target == 0:
count_divisible_subarrays += 1
return count_divisible_subarrays
The best way to solve this is to keep track of the remainders when you divide the running sums of the numbers by the given divisor. By using a clever shortcut with these remainders, you can quickly count the subarrays that add up to a multiple of the divisor without checking every single possibility.
Here's how the algorithm would work step-by-step:
def subarray_sums_divisible_by_k(number_list, divisor):
running_sum = 0
subarray_count = 0
remainder_counts = {0: 1}
for number in number_list:
running_sum += number
remainder = running_sum % divisor
# If negative, adjust remainder to be positive.
if remainder < 0:
remainder += divisor
# Count subarrays that sum to a multiple of k.
if remainder in remainder_counts:
subarray_count += remainder_counts[remainder]
# Update count of remainders.
if remainder in remainder_counts:
remainder_counts[remainder] += 1
else:
remainder_counts[remainder] = 1
return subarray_count
Case | How to Handle |
---|---|
Empty or null input array | Return 0, as there are no subarrays in an empty array. |
k is zero | Return 0, as division by zero is undefined and no sum can be divisible by 0 (unless the sum is also 0, which requires special handling). |
Array with only one element | Check if the single element is divisible by k; return 1 if so, 0 otherwise. |
Array with all elements equal to zero | The number of subarrays is n*(n+1)/2, where n is the array length, and return that as all subarray sums are 0, which is divisible by k for any non-zero k. |
Array with all negative numbers | The prefix sum can become very negative, so use modulo operator carefully to handle negative remainders (add k until positive). |
Large input array and large k value | The prefix sums should use long data type to avoid integer overflow. |
k is a large number compared to elements in nums | Many remainders will likely be unique, so the HashMap can grow significantly, potentially impacting performance. |
Integer overflow of sum within subarray | Use a long data type to store the running sum to avoid potential overflow issues. |