Problem
Given an array of integers, find subarray such that sum of elements in the element is divisible by k.
Examples
Example 1:
Input: nums = [4,5,0,-2,-3,1], k = 5
Output: [4, 5, 0, -2, -3, 1]
Explanation: The sum of the output subarray is 5, which is divisible by 5.
Example 2:
Input: nums = [2, 7, 6, 1, 4, 5], k = 3
Output: [2, 7, 6]
Explanation: The subarray [2, 7, 6] has a sum of 15, which is divisible by 3.
Similar Problem
Subarray Sums Divisible by K Problem
Solution
Method 1 - Using Prefix sum and modulo k
- Prefix Sum and Modulo:
- Use a dictionary to store the first occurrence of each prefix sum modulo
k
.
- Use a dictionary to store the first occurrence of each prefix sum modulo
- Collision Principle:
- If two prefix sums have the same remainder when divided by
k
, the elements between these two prefix sums form a subarray whose sum is divisible byk
.
- If two prefix sums have the same remainder when divided by
Code
Java
public class Solution {
public int[] subarrayDivByK(int[] nums, int k) {
Map<Integer, Integer> prefixSumModMap = new HashMap<>();
prefixSumModMap.put(0, -1);
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
int mod = ((sum % k) + k) % k;
if (prefixSumModMap.containsKey(mod)) {
int start = prefixSumModMap.get(mod) + 1;
int end = i;
int[] result = new int[end - start + 1];
for (int j = start; j <= end; j++) {
result[j - start] = nums[j];
}
return result;
}
prefixSumModMap.put(mod, i);
}
return new int[0];
}
public static void main(String[] args) {
Solution sol = new Solution();
int[] nums1 = {2, 7, 6, 1, 4, 5};
int k1 = 3;
int[] result1 = sol.subarrayDivByK(nums1, k1);
System.out.println("Subarray: " + java.util.Arrays.toString(result1)); // Expected output: [2, 7, 6]
int[] nums2 = {1, 3, 2, 6, 4};
int k2 = 7;
int[] result2 = sol.subarrayDivByK(nums2, k2);
System.out.println("Subarray: " + java.util.Arrays.toString(result2)); // Expected output: [3, 2, 6]
}
}
Python
class Solution:
def subarrayDivByK(self, nums: List[int], k: int) -> List[int]:
prefix_sum_mod_map = {0: -1}
total_sum = 0
for i in range(len(nums)):
total_sum += nums[i]
mod = ((total_sum % k) + k) % k
if mod in prefix_sum_mod_map:
start = prefix_sum_mod_map[mod] + 1
end = i
return nums[start:end + 1]
prefix_sum_mod_map[mod] = i
return []
# Example usage
sol = Solution()
nums1 = [2, 7, 6, 1, 4, 5]
k1 = 3
result1 = sol.subarrayDivByK(nums1, k1)
print("Subarray:", result1) # Expected output: [2, 7, 6]
nums2 = [1, 3, 2, 6, 4]
k2 = 7
result2 = sol.subarrayDivByK(nums2, k2)
print("Subarray:", result2) # Expected output: [3, 2, 6]
Complexity
- ⏰ Time complexity:
O(n)
, wheren
is the number of elements in the array because we traverse the array once. - 🧺 Space complexity:
O(n)
, for storing the prefix sums and their indices in a dictionary.
Similar Problem
Another variation of this problem could be:
Given an array of integers, find max length subarray such that sum of elements in the element is divisible by a given number k.
Similar to above approach, but instead of keeping a single index for each prefix sum modulo k
, we maintain a list of indices with the same prefix sum modulo k
. Each pair of indices from these lists represents a potential subarray. Continuously update the maximum size from these candidate subarrays to find the answer.