Given an integer array arr
, and an integer target
, return the number of tuples i, j, k
such that i < j < k
and arr[i] + arr[j] + arr[k] == target
.
As the answer can be very large, return it modulo 109 + 7
.
Example 1:
Input: arr = [1,1,2,2,3,3,4,4,5,5], target = 8 Output: 20 Explanation: Enumerating by the values (arr[i], arr[j], arr[k]): (1, 2, 5) occurs 8 times; (1, 3, 4) occurs 8 times; (2, 2, 4) occurs 2 times; (2, 3, 3) occurs 2 times.
Example 2:
Input: arr = [1,1,2,2,2,2], target = 5 Output: 12 Explanation: arr[i] = 1, arr[j] = arr[k] = 2 occurs 12 times: We choose one 1 from [1,1] in 2 ways, and two 2s from [2,2,2,2] in 6 ways.
Example 3:
Input: arr = [2,1,3], target = 6 Output: 1 Explanation: (1, 2, 3) occured one time in the array so we return 1.
Constraints:
3 <= arr.length <= 3000
0 <= arr[i] <= 100
0 <= target <= 300
This problem asks to find the number of triplets (i, j, k) in an array arr
such that i < j < k
and arr[i] + arr[j] + arr[k] == target
. The solution presented uses a counting approach to efficiently handle potential duplicates within the array.
Approach:
Counting Occurrences: First, we count the occurrences of each element in the input array arr
. This is done efficiently using a hash map (or an array if the range of elements is known and relatively small, as in this case where elements are in the range [0, 100]). This step takes O(n) time, where n is the length of arr
.
Iterative Triplet Search: We iterate through the array arr
. For each element arr[j]
, we do the following:
Decrement Count: We decrement the count of arr[j]
in the counter. This is crucial because we're going to consider arr[j]
as part of a potential triplet, and we want to avoid counting the same element multiple times within the triplet.
Inner Loop: We iterate through the elements before arr[j]
(i.e., arr[i]
where i < j
). For each arr[i]
, we calculate c = target - arr[i] - arr[j]
. c
represents the third element needed to sum up to the target
.
Check and Add: If c
exists in the counter (i.e., it's a valid element in the array and its count is greater than 0), we add its count (cnt[c]
) to the total count of triplets (ans
). This implicitly considers all possible combinations with the chosen arr[i]
and arr[j]
.
Modulo Operation: We apply the modulo operation (% (10**9 + 7)
) after each addition to prevent integer overflow, as the problem specifies.
Return Result: Finally, we return the total count of triplets (ans
).
Time and Space Complexity:
Time Complexity: O(n^2). The nested loops dominate the runtime. The initial counting step is O(n).
Space Complexity: O(C), where C is the range of elements in arr
. In this problem, C = 101 (0 to 100). The space used is primarily for the counter. If the range of elements were unbounded, a hash map would be needed resulting in O(n) space complexity in the worst case.
Code Examples (Python):
from collections import Counter
class Solution:
def threeSumMulti(self, arr: List[int], target: int) -> int:
mod = 10**9 + 7
cnt = Counter(arr)
ans = 0
for j, b in enumerate(arr):
cnt[b] -= 1
for i in range(j):
a = arr[i]
c = target - a - b
if c >= 0 and c <= 100 and cnt[c] > 0:
ans = (ans + cnt[c]) % mod
return ans
The code in other languages (Java, C++, Go, TypeScript) follows the same logic and algorithmic structure, differing only in syntax and standard library usage. The core idea of counting and iterative triplet search remains consistent across all implementations.