You are given an array of integers nums
and an integer k
.
Return the maximum sum of a subarray of nums
, such that the size of the subarray is divisible by k
.
Example 1:
Input: nums = [1,2], k = 1
Output: 3
Explanation:
The subarray [1, 2]
with sum 3 has length equal to 2 which is divisible by 1.
Example 2:
Input: nums = [-1,-2,-3,-4,-5], k = 4
Output: -10
Explanation:
The maximum sum subarray is [-1, -2, -3, -4]
which has length equal to 4 which is divisible by 4.
Example 3:
Input: nums = [-5,1,2,-3,4], k = 2
Output: 4
Explanation:
The maximum sum subarray is [1, 2, -3, 4]
which has length equal to 4 which is divisible by 2.
Constraints:
1 <= k <= nums.length <= 2 * 105
-109 <= nums[i] <= 109
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:
The brute force strategy involves checking every possible consecutive group of numbers within the given set. For each group, we determine if the group's size is evenly divisible by a specific number, and if so, calculate and keep track of the group's total sum.
Here's how the algorithm would work step-by-step:
def max_subarray_sum_divisible_by_k_brute_force(number_list, divisor):
maximum_sum = float('-inf')
for start_index in range(len(number_list)):
for end_index in range(start_index, len(number_list)):
# Creating the sub array that ends at end_index
sub_array = number_list[start_index:end_index + 1]
# Check if the sub array length is divisible by k
if len(sub_array) % divisor == 0:
current_sum = sum(sub_array)
# Keep track of the largest sum we have found
if current_sum > maximum_sum:
maximum_sum = current_sum
return maximum_sum
The goal is to find the biggest possible sum from a continuous section of numbers where the length of that section is perfectly divisible by K. Instead of checking every possible section, we use a clever trick to keep track of potential starting points that might lead to the best answer.
Here's how the algorithm would work step-by-step:
def max_subarray_sum_divisible_by_k(numbers, k):
maximum_sum = float('-inf')
current_running_sum = 0
remainder_first_occurrence = {}
# Initialize remainder 0 to index -1 to handle subarrays
# starting from the beginning of the input array
remainder_first_occurrence[0] = -1
for index, number in enumerate(numbers):
current_running_sum += number
current_remainder = current_running_sum % k
# Store the first occurrence of each remainder to calculate
# subarray sums divisible by k.
if current_remainder not in remainder_first_occurrence:
remainder_first_occurrence[current_remainder] = index
# Calculate the subarray sum and update the maximum sum
# if a larger sum is found
else:
subarray_sum = current_running_sum - \
sum(numbers[remainder_first_occurrence[current_remainder]+1:index+1])
subarray_sum = current_running_sum - \
sum(numbers[remainder_first_occurrence[current_remainder]+1:index+1])
maximum_sum = max(maximum_sum, current_running_sum - numbers[remainder_first_occurrence[current_remainder]+1])
subarray_sum = current_running_sum - numbers[remainder_first_occurrence[current_remainder]+1]
maximum_sum = max(maximum_sum, subarray_sum)
start_index = remainder_first_occurrence[current_remainder] + 1
end_index = index + 1
subarray_sum = sum(numbers[start_index:end_index])
maximum_sum = max(maximum_sum, subarray_sum)
maximum_sum = max(maximum_sum, current_running_sum - sum(numbers[:remainder_first_occurrence[current_remainder] + 1]))
# Calculate the subarray sum using the prefix sum technique
subarray_sum = current_running_sum - sum(numbers[0 : remainder_first_occurrence[current_remainder] + 1])
maximum_sum = max(maximum_sum, subarray_sum)
subarray_sum = current_running_sum - sum(numbers[:remainder_first_occurrence[current_remainder] + 1])
# Ensure the length is divisible by k
if (index - remainder_first_occurrence[current_remainder]) % k == 0:
maximum_sum = max(maximum_sum, current_running_sum - sum(numbers[:remainder_first_occurrence[current_remainder]+1]))
return maximum_sum
Case | How to Handle |
---|---|
Null or empty input array | Return 0 immediately, as no subarray sum is possible. |
Array with a single element | Return the element if it is divisible by K, otherwise return 0. |
All elements are negative and K is larger than the array length. | Return 0 since no positive or zero sum subarray of length divisible by K exists. |
Array contains only zeros. | Return the sum of all elements (which is 0) if the array length is divisible by K, otherwise return 0. |
Array contains very large positive numbers causing integer overflow | Use a data type that can handle larger numbers, like long, or calculate prefix sums modulo K to prevent overflow and track the modulo value instead of the actual sum. |
K is 1 | Return the sum of the entire array as its length is trivially divisible by 1. |
K is 0 | Throw an IllegalArgumentException or return an appropriate error code, since division by zero is undefined. |
Very large input array causing memory issues | Consider a streaming approach or divide and conquer to process the input in smaller chunks, if possible, based on the constraints and algorithm used. |