The Indian Engineer

Problem 1590 Make Sum Divisible by P

Posted on 7 mins

Array Hash-Table Prefix-Sum

Problem Statement

Link - Problem 1590

Question

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:

Solution

class Solution {
public:
    int minSubarray(vector<int>& nums, int p) {
        int n = nums.size();
        int totalSum = 0;

        for (int num : nums) {
            totalSum = (totalSum + num) % p;
        }

        int target = totalSum % p;
        if (target == 0)
            return 0;

        unordered_map<int, int> modMap;
        modMap[0] = -1;
        int currentSum = 0, minLen = n;

        for (int i = 0; i < n; ++i) {
            currentSum = (currentSum + nums[i]) % p;

            int needed = (currentSum - target + p) % p;

            if (modMap.find(needed) != modMap.end()) {
                minLen = min(minLen, i - modMap[needed]);
            }
            modMap[currentSum] = i;
        }

        return minLen == n ? -1 : minLen;
    }
};

Complexity Analysis

| Algorithm                      | Time Complexity | Space Complexity |
| ------------------------------ | --------------- | ---------------- |
| Sliding Window with Hash Table | O(n)            | O(n)             |

Explanation

Intial Thoughts

To approach this problem, we should first calculate the total sum of the array and its remainder when divided by p. If the remainder is zero, then we don’t need to remove any subarray. We should also think about using a hashmap to store the prefix sums and their indices. We can then iterate over the array, updating the current sum and checking if there’s a prefix sum that can help us find a subarray to remove. Key points to consider are: calculating the total sum, finding the target remainder, using a hashmap for prefix sums, and iterating over the array to find the smallest subarray to remove.

Intuitive Analysis

Intuitively, we can think of this problem as trying to find a ‘balance point’ in the array where removing a subarray would make the remaining sum divisible by p. We can use the concept of prefix sums and modular arithmetic to find this balance point. We should consider the following points: the remainder of the total sum when divided by p gives us the target, we can use a sliding window approach to find the smallest subarray, the hashmap helps us keep track of the prefix sums and their indices, and by iterating over the array and updating the current sum, we can find the smallest subarray that needs to be removed to make the remaining sum divisible by p. Additionally, we should also think about handling edge cases, such as when the smallest subarray to remove is the whole array, in which case we return -1.

1. Intuition

2. Implementation


Complexity Analysis

Time Complexity:

Space Complexity:


Footnote

This question is rated as Medium difficulty.

Hints

Use prefix sums to calculate the subarray sums.

Suppose you know the remainder for the sum of the entire array. How does removing a subarray affect that remainder? What remainder does the subarray need to have in order to make the rest of the array sum up to be divisible by k?

Use a map to keep track of the rightmost index for every prefix sum % p.


Similar Questions:

Title URL Difficulty
Subarray Sums Divisible by K https://leetcode.com/problems/subarray-sums-divisible-by-k Medium
Find the Divisibility Array of a String https://leetcode.com/problems/find-the-divisibility-array-of-a-string Medium