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 10^9 + 7
.
For example:
arr = [1,1,2,2,3,3,4,4,5,5], target = 8
. Expected output: 20. The triplets are (1, 2, 5), (1, 3, 4), (2, 2, 4), and (2, 3, 3), occurring 8, 8, 2, and 2 times respectively.arr = [1,1,2,2,2,2], target = 5
. Expected output: 12. 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.arr = [2,1,3], target = 6
. Expected output: 1. The triplet (1, 2, 3) occurs once.Constraints:
3 <= arr.length <= 3000
0 <= arr[i] <= 100
0 <= target <= 300
How would you approach this problem, considering the constraints and potential for large outputs? Can you provide an optimized solution to count the number of triplets that sum to the target, while avoiding integer overflows and handling duplicate values efficiently?
A naive solution would involve iterating through all possible triplets in the array and checking if their sum equals the target. This approach is straightforward but inefficient.
def threeSumMulti_brute_force(arr, target):
count = 0
n = len(arr)
for i in range(n):
for j in range(i + 1, n):
for k in range(j + 1, n):
if arr[i] + arr[j] + arr[k] == target:
count += 1
return count % (10**9 + 7)
To improve efficiency, we can use a counting-based approach. We count the occurrences of each number in the array using a Counter
. Then, we iterate through all possible pairs of numbers and check if the third number needed to reach the target exists in the Counter
. We handle cases where the numbers are the same carefully to avoid overcounting.
from collections import Counter
def threeSumMulti(arr, target):
count = Counter(arr)
ans = 0
mod = 10**9 + 7
for i in count:
for j in count:
k = target - i - j
if k not in count:
continue
if i == j == k:
ans += count[i] * (count[i] - 1) * (count[i] - 2) // 6
elif i == j:
ans += count[i] * (count[i] - 1) // 2 * count[k]
elif i < j < k:
ans += count[i] * count[j] * count[k]
ans %= mod
return ans