Given an array of positive integers nums
, remove the smallest subarray (possibly empty) such that the sum of the remaining elements is divisible by p
. It is not allowed to remove the whole array.
Return the length of the smallest subarray that you need to remove, or -1
if it's impossible.
A subarray is defined as a contiguous block of elements in the array.
Example 1:
Input: nums = [3,1,4,2], p = 6 Output: 1 Explanation: The sum of the elements in nums is 10, which is not divisible by 6. We can remove the subarray [4], and the sum of the remaining elements is 6, which is divisible by 6.
Example 2:
Input: nums = [6,3,5,2], p = 9 Output: 2 Explanation: We cannot remove a single element to get a sum divisible by 9. The best way is to remove the subarray [5,2], leaving us with [6,3] with sum 9.
Example 3:
Input: nums = [1,2,3], p = 3 Output: 0 Explanation: Here the sum is 6. which is already divisible by 3. Thus we do not need to remove anything.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 109
1 <= p <= 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 method for this problem involves checking every possible part of the list of numbers. We want to find the smallest part we can remove so that the sum of the remaining numbers is evenly divisible by a given number.
Here's how the algorithm would work step-by-step:
def make_sum_divisible_by_p_brute_force(numbers, divisor):
list_length = len(numbers)
total_sum = sum(numbers)
for removal_count in range(list_length + 1):
for indices_to_remove in combinations(range(list_length), removal_count):
current_sum = total_sum
# Subtract the numbers at the indices being removed
for index in indices_to_remove:
current_sum -= numbers[index]
# Check if the remaining numbers are divisible by the divisor
if current_sum % divisor == 0:
return removal_count
return list_length
from itertools import combinations
The key idea is to find a smallest segment we can remove from the list, such that the remaining list sums to a multiple of the given number. To do this efficiently, we look for a segment whose sum is equal to the original sum's remainder after division.
Here's how the algorithm would work step-by-step:
def make_sum_divisible_by_p(numbers, divisor):
list_length = len(numbers)
total_sum = sum(numbers)
remainder = total_sum % divisor
# If the remainder is 0, no removal needed.
if remainder == 0:
return 0
prefix_remainder_index = {0: -1}
min_removal_length = list_length
current_sum = 0
for index, number in enumerate(numbers):
current_sum = (current_sum + number) % divisor
# We look for a sub-array with sum equal to the original remainder.
required_remainder = (current_sum - remainder) % divisor
if required_remainder in prefix_remainder_index:
current_removal_length = index - prefix_remainder_index[required_remainder]
min_removal_length = min(min_removal_length, current_removal_length)
# Store the earliest index of the current remainder.
if current_sum not in prefix_remainder_index:
prefix_remainder_index[current_sum] = index
# If no valid sub-array is found, remove the entire list.
if min_removal_length == list_length:
return -1
return min_removal_length
Case | How to Handle |
---|---|
Empty input array | Return 0 if the sum is already divisible by p; otherwise return -1 since no subarray can be removed from an empty array to affect divisibility. |
Input array of length 1 | If the element is not divisible by p, return 1; otherwise, return 0 if the initial sum was divisible, or -1 if it isn't and we cannot remove. |
Initial sum is already divisible by p | Return 0 because no subarray needs to be removed. |
No subarray exists that satisfies the condition | Return -1 when no valid subarray can be found, indicating the task is impossible. |
Large input array causing potential integer overflow when calculating the sum | Use modulo operator (%) after each addition to prevent integer overflow. |
p equals 1 | Return 0 since any number is divisible by 1. |
All elements in the array are divisible by p | If the initial sum is divisible by p, return 0; otherwise, return 1 if removing a single element makes the remaining sum divisible by p, and -1 otherwise. |
The required remainder does not appear in the prefix sums | Return -1, indicating no such subarray can be removed to make the sum divisible by p. |