Problem
Given an array of integers arr
of even length n
and an integer k
.
We want to divide the array into exactly n / 2
pairs such that the sum of each pair is divisible by k
.
Return true
If you can find a way to do that or false
otherwise.
Examples
Example 1:
Input: arr = [1,2,3,4,5,10,6,7,8,9], k = 5
Output: true
Explanation: Pairs are (1,9),(2,8),(3,7),(4,6) and (5,10).
Example 2:
Input: arr = [1,2,3,4,5,6], k = 7
Output: true
Explanation: Pairs are (1,6),(2,5) and(3,4).
Example 3:
Input: arr = [1,2,3,4,5,6], k = 10
Output: false
Explanation: You can try all possible pairs to see that there is no way to divide arr into 3 pairs each with sum divisible by 10.
Solution
Method 1 - Using Frequency array
Suppose, we are given two numbers a
and b
:
- Then, If
a % k == x
andb % k == k - x
, then(a + b)
is divisible byk
i.e. (a + b) % k = 0.
Lets prove this:
a % k = x
b % k = k - x
(a + b) % k = ((a + b) % k) % k
= (a % k + b % k) % k
= (x + k - x) % k
= k % k = 0
Approach
Here is the approach:
- Create Frequency Array: Initialize an array
freq
of sizek
to zero. - Fill Frequency Array: For each element in the array, calculate its remainder
rem
when divided byk
. Ifrem
is negative, addk
to it to ensure it is positive. Increment the corresponding index in thefreq
array. - Validate Remainder Frequencies:
- For each
i
from 1 tok-1
, check iffreq[i]
equalsfreq[k - i]
. - Check if
freq[0]
is even.
- For each
- Return Result: If all conditions are satisfied, return
true
; otherwise, returnfalse
.
Video explanation
Here is the video explaining this method in detail. Please check it out:
Code
Java
public class Solution {
public boolean canArrange(int[] arr, int k) {
// Create a frequency array to count occurrences
// of all remainders when divided by k
int[] freq = new int[k];
// Fill remainder frequency array
for (int num : arr) {
int rem = num % k;
if (rem < 0) {
rem += k;
}
freq[rem]++;
}
// Check if frequency of remainders satisfies the pair condition
for (int i = 1; i < k; i++) {
if (freq[i] != freq[k - i]) {
return false;
}
}
// Special check for remainder 0 elements, count of such elements must
// be even
return freq[0] % 2 == 0;
}
}
Python
class Solution:
def canArrange(self, arr: List[int], k: int) -> bool:
# If the array length is odd, we cannot divide it into pairs
if len(arr) % 2 != 0:
return False
# Create a frequency array to count occurrences of all remainders when divided by k
freq = [0] * k
# Fill remainder frequency array
for num in arr:
rem = num % k
if rem < 0:
rem += k
freq[rem] += 1
# Check if frequency of remainders satisfies the pair condition
for i in range(1, k):
if freq[i] != freq[k - i]:
return False
# Special check for remainder 0 elements, count of such elements must be even
return freq[0] % 2 == 0
Complexity
- ⏰ Time complexity:
O(n + k)
, wheren
is the length of the array. We make a single pass through the array to populate the frequency array which takesO(n)
and another pass to check the remainder conditions which takesO(k)
. - 🧺 Space complexity:
O(k)
for storing the remainder frequencies in an array of sizek
.