Number of Divisible Triplet Sums
MediumUpdated: Aug 2, 2025
Practice on:
Problem
Given a 0-indexed integer array nums and an integer d, return the number of triplets (i, j, k) such that i < j < k and (nums[i] + nums[j] + nums[k]) % d == 0.
Examples
Example 1:
Input: nums = [3,3,4,7,8], d = 5
Output: 3
Explanation: The triplets which are divisible by 5 are: (0, 1, 2), (0, 2, 4), (1, 2, 4).
It can be shown that no other triplet is divisible by 5. Hence, the answer is 3.
Example 2:
Input: nums = [3,3,3,3], d = 3
Output: 4
Explanation: Any triplet chosen here has a sum of 9, which is divisible by 3. Hence, the answer is the total number of triplets which is 4.
Example 3:
Input: nums = [3,3,3,3], d = 6
Output: 0
Explanation: Any triplet chosen here has a sum of 9, which is not divisible by 6. Hence, the answer is 0.
Constraints:
1 <= nums.length <= 10001 <= nums[i] <= 10^91 <= d <= 10^9
Solution
Method 1 – Hash Map for Pair Sums
Intuition
For each k, count pairs (i, j) with i < j < k such that (nums[i] + nums[j] + nums[k]) % d == 0. For each k, keep a hash map of pair sums modulo d for all previous i, j.
Approach
- For each k from 2 to n-1:
- For each j in 0..k-1, store (nums[i] + nums[j]) % d for i < j in a hash map.
- For each pair sum mod, if (pair_sum + nums[k]) % d == 0, add its count to answer.
- Return total answer.
Code
C++
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
int divisibleTripletSums(vector<int>& nums, int d) {
int n = nums.size(), ans = 0;
for (int k = 2; k < n; ++k) {
unordered_map<int,int> cnt;
for (int i = 0; i < k; ++i)
for (int j = i+1; j < k; ++j)
cnt[(nums[i]+nums[j])%d]++;
int need = (d - nums[k]%d)%d;
ans += cnt[need];
}
return ans;
}
};
Go
func divisibleTripletSums(nums []int, d int) int {
n, ans := len(nums), 0
for k := 2; k < n; k++ {
cnt := map[int]int{}
for i := 0; i < k; i++ {
for j := i+1; j < k; j++ {
cnt[(nums[i]+nums[j])%d]++
}
}
need := (d - nums[k]%d)%d
ans += cnt[need]
}
return ans
}
Java
import java.util.*;
class Solution {
public int divisibleTripletSums(int[] nums, int d) {
int n = nums.length, ans = 0;
for (int k = 2; k < n; ++k) {
Map<Integer,Integer> cnt = new HashMap<>();
for (int i = 0; i < k; ++i)
for (int j = i+1; j < k; ++j)
cnt.put((nums[i]+nums[j])%d, cnt.getOrDefault((nums[i]+nums[j])%d,0)+1);
int need = (d - nums[k]%d)%d;
ans += cnt.getOrDefault(need,0);
}
return ans;
}
}
Kotlin
class Solution {
fun divisibleTripletSums(nums: IntArray, d: Int): Int {
val n = nums.size
var ans = 0
for (k in 2 until n) {
val cnt = mutableMapOf<Int,Int>()
for (i in 0 until k)
for (j in i+1 until k)
cnt[(nums[i]+nums[j])%d] = cnt.getOrDefault((nums[i]+nums[j])%d,0)+1
val need = (d - nums[k]%d)%d
ans += cnt.getOrDefault(need,0)
}
return ans
}
}
Python
class Solution:
def divisibleTripletSums(self, nums: list[int], d: int) -> int:
n, ans = len(nums), 0
for k in range(2, n):
cnt = {}
for i in range(k):
for j in range(i+1, k):
cnt[(nums[i]+nums[j])%d] = cnt.get((nums[i]+nums[j])%d,0)+1
need = (d - nums[k]%d)%d
ans += cnt.get(need,0)
return ans
Rust
use std::collections::HashMap;
impl Solution {
pub fn divisible_triplet_sums(nums: Vec<i32>, d: i32) -> i32 {
let n = nums.len();
let mut ans = 0;
for k in 2..n {
let mut cnt = HashMap::new();
for i in 0..k {
for j in i+1..k {
*cnt.entry((nums[i]+nums[j])%d).or_insert(0) += 1;
}
}
let need = (d - nums[k]%d)%d;
ans += *cnt.get(&need).unwrap_or(&0);
}
ans
}
}
TypeScript
class Solution {
divisibleTripletSums(nums: number[], d: number): number {
const n = nums.length;
let ans = 0;
for (let k = 2; k < n; ++k) {
const cnt: Record<number, number> = {};
for (let i = 0; i < k; ++i)
for (let j = i+1; j < k; ++j)
cnt[(nums[i]+nums[j])%d] = (cnt[(nums[i]+nums[j])%d]||0)+1;
const need = (d - nums[k]%d)%d;
ans += cnt[need]||0;
}
return ans;
}
}
Complexity
- ⏰ Time complexity:
O(n^3), where n is the length of nums. - 🧺 Space complexity:
O(n^2).