Make Sum Divisible by P - Complete Solution Guide
Make Sum Divisible by P is LeetCode problem 1590, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
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
Detailed Explanation
The problem requires finding the smallest subarray within a given array `nums` of positive integers such that removing this subarray makes the sum of the remaining elements divisible by `p`. The entire array cannot be removed. The input consists of the array `nums` and the divisor `p`. The output is the length of the smallest subarray that needs to be removed, or -1 if it's impossible to make the sum divisible by `p`.
Solution Approach
The solution utilizes the concept of prefix sums and remainders to efficiently identify the smallest subarray to remove. First, it calculates the total sum of the array and its remainder when divided by `p`. If the remainder is 0, the sum is already divisible by `p`, and the answer is 0. Otherwise, it iterates through the array, maintaining a running sum of the elements modulo `p`. For each index, it calculates the remainder needed to be removed (`rem_to_find`) and checks if a prefix remainder exists in the hash map such that the difference between the current index and the index of that prefix remainder equals `rem_to_find`. The hash map stores the prefix remainders and their corresponding indices, allowing for quick lookups. The smallest length of the subarray found is then updated.
Step-by-Step Algorithm
- Step 1: Calculate the total sum of the array `nums` and compute `target_rem` as the remainder of the total sum when divided by `p`.
- Step 2: If `target_rem` is 0, the array sum is already divisible by `p`, return 0.
- Step 3: Initialize a hash map `prefix_rem_map` to store prefix remainders and their indices. Add `(0, -1)` to the map to handle cases where the subarray starts from index 0.
- Step 4: Initialize `current_rem` to 0 and `min_len` to the length of `nums`.
- Step 5: Iterate through `nums` from index 0 to `n-1`.
- Step 6: Update `current_rem` by adding the current element `nums[i]` and taking the modulo by `p`.
- Step 7: Calculate `rem_to_find` as the remainder needed to reach divisibility: `(current_rem - target_rem + p) % p`.
- Step 8: Check if `rem_to_find` exists as a key in `prefix_rem_map`. If it does, calculate the length of the subarray to remove as `i - prefix_rem_map[rem_to_find]` and update `min_len` if this length is smaller.
- Step 9: Add the current remainder `current_rem` and its index `i` to the `prefix_rem_map`.
- Step 10: After iterating through the entire array, if `min_len` is still equal to the initial value (length of `nums`), it means no valid subarray was found, return -1. Otherwise, return `min_len`.
Key Insights
- Insight 1: The problem can be reframed as finding a subarray whose sum has the same remainder as the total sum of the array when divided by `p`.
- Insight 2: Prefix sums and a hash map can efficiently track remainders seen so far and their corresponding indices.
- Insight 3: Modulo operations are crucial to keep the numbers within a manageable range, especially given the large constraints.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(n)
Topics
This problem involves: Array, Hash Table, Prefix Sum.
Companies
Asked at: PhonePe, Samsung.