Skip to content

Commit 428b287

Browse files
Create 0923-3sum-with-multiplicity.md
Add slution to the lc problem 923 3sum-with-multiplicity using python java cpp c and js
1 parent db3e58f commit 428b287

File tree

1 file changed

+300
-0
lines changed

1 file changed

+300
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
---
2+
id: 3sum-with-multiplicity
3+
title: Three Sum With Multiplicity
4+
sidebar_label: 3Sum-with-multiplicity
5+
tags:
6+
- Array
7+
- Hash Map
8+
- Combinatorics
9+
- Two Pointers
10+
---
11+
12+
## Problem Description
13+
14+
| Problem Statement | Solution Link | LeetCode Profile |
15+
| :------------------------------------------------------ | :------------------------------------------------------------------------- | :------------------------------------------------------ |
16+
| [3sum-with-multiplicity](https://leetcode.com/problems/3sum-with-multiplicity/description/) | [3sum-with-multiplicity Solution on LeetCode](https://leetcode.com/problems/3sum-with-multiplicity/solutions/) | [Nikita Saini](https://leetcode.com/u/Saini_Nikita/) |
17+
## Problem Description
18+
19+
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`.
20+
21+
As the answer can be very large, return it modulo 10^9 + 7.
22+
23+
### Example 1:
24+
**Input:** `arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5], target = 8`
25+
**Output:** `20`
26+
**Explanation:**
27+
`Enumerating by the values (arr[i], arr[j], arr[k]):
28+
(1, 2, 5) occurs 8 times;
29+
(1, 3, 4) occurs 8 times;
30+
(2, 2, 4) occurs 2 times;
31+
(2, 3, 3) occurs 2 times.`
32+
33+
### Example 2:
34+
**Input:** `arr = [1, 1, 2, 2, 2, 2], target = 5`
35+
**Output:** `12`
36+
**Explanation:**
37+
`arr[i] = 1, arr[j] = arr[k] = 2 occurs 12 times:
38+
We choose one 1 from [1,1] in 2 ways,
39+
and two 2s from [2,2,2,2] in 6 ways.`
40+
41+
### Example 3:
42+
**Input:** `arr = [2, 1, 3], target = 6`
43+
**Output:** `1`
44+
**Explanation:** `(1, 2, 3) occurred one time in the array so we return 1.`
45+
46+
### Constraints:
47+
- `3 <= arr.length <= 3000`
48+
- `0 <= arr[i] <= 100`
49+
- `0 <= target <= 300`
50+
51+
## Approach
52+
53+
To solve this problem, we can use a combination of counting and two-pointer techniques. Here is a step-by-step approach:
54+
55+
1. **Count the Occurrences**: Use a hashmap to count the occurrences of each element in the array.
56+
2. **Find Triplets**: Iterate over each pair of elements and check if the third element needed to reach the target exists in the hashmap.
57+
3. **Handle Different Cases**: Depending on the values of the three elements, handle different counting cases (all three equal, two equal, all different).
58+
4. **Modulo Operation**: Use modulo 10^9 + 7 to ensure the result doesn't overflow.
59+
60+
## Solution
61+
62+
### Python
63+
```python
64+
from collections import Counter
65+
66+
class Solution:
67+
def threeSumMulti(self, arr, target):
68+
MOD = 10**9 + 7
69+
count = Counter(arr)
70+
keys = sorted(count)
71+
result = 0
72+
73+
for i, x in enumerate(keys):
74+
T = target - x
75+
j, k = i, len(keys) - 1
76+
while j <= k:
77+
y, z = keys[j], keys[k]
78+
if y + z < T:
79+
j += 1
80+
elif y + z > T:
81+
k -= 1
82+
else:
83+
if i < j < k:
84+
result += count[x] * count[y] * count[z]
85+
elif i == j < k:
86+
result += count[x] * (count[x] - 1) // 2 * count[z]
87+
elif i < j == k:
88+
result += count[x] * count[y] * (count[y] - 1) // 2
89+
else: # i == j == k
90+
result += count[x] * (count[x] - 1) * (count[x] - 2) // 6
91+
result %= MOD
92+
j += 1
93+
k -= 1
94+
95+
return result
96+
```
97+
98+
### Java
99+
```java
100+
import java.util.HashMap;
101+
import java.util.Map;
102+
103+
class Solution {
104+
public int threeSumMulti(int[] arr, int target) {
105+
int MOD = 1_000_000_007;
106+
Map<Integer, Long> count = new HashMap<>();
107+
108+
for (int num : arr) {
109+
count.put(num, count.getOrDefault(num, 0L) + 1);
110+
}
111+
112+
long result = 0;
113+
114+
for (int i : count.keySet()) {
115+
for (int j : count.keySet()) {
116+
int k = target - i - j;
117+
if (count.containsKey(k)) {
118+
long ci = count.get(i);
119+
long cj = count.get(j);
120+
long ck = count.get(k);
121+
122+
if (i == j && j == k) {
123+
result += ci * (ci - 1) * (ci - 2) / 6; // C(ci, 3)
124+
} else if (i == j && j != k) {
125+
result += ci * (ci - 1) / 2 * ck; // C(ci, 2) * ck
126+
} else if (i < j && j < k) {
127+
result += ci * cj * ck; // ci * cj * ck
128+
}
129+
}
130+
}
131+
}
132+
133+
return (int)(result % MOD);
134+
}
135+
}
136+
```
137+
138+
### C++
139+
```cpp
140+
#include <vector>
141+
#include <unordered_map>
142+
143+
using namespace std;
144+
145+
class Solution {
146+
public:
147+
int threeSumMulti(vector<int>& arr, int target) {
148+
const int MOD = 1'000'000'007;
149+
unordered_map<int, long> count;
150+
151+
for (int num : arr) {
152+
count[num]++;
153+
}
154+
155+
long result = 0;
156+
157+
for (auto i : count) {
158+
for (auto j : count) {
159+
int k = target - i.first - j.first;
160+
if (count.find(k) != count.end()) {
161+
long ci = i.second;
162+
long cj = j.second;
163+
long ck = count[k];
164+
165+
if (i.first == j.first && j.first == k) {
166+
result += ci * (ci - 1) * (ci - 2) / 6;
167+
} else if (i.first == j.first && j.first != k) {
168+
result += ci * (ci - 1) / 2 * ck;
169+
} else if (i.first < j.first && j.first < k) {
170+
result += ci * cj * ck;
171+
}
172+
}
173+
}
174+
}
175+
176+
return result % MOD;
177+
}
178+
};
179+
```
180+
181+
### C
182+
```c
183+
#include <stdio.h>
184+
#include <stdlib.h>
185+
186+
#define MOD 1000000007
187+
188+
typedef struct {
189+
int key;
190+
long value;
191+
} HashMap;
192+
193+
int compare(const void *a, const void *b) {
194+
return ((HashMap *)a)->key - ((HashMap *)b)->key;
195+
}
196+
197+
int threeSumMulti(int* arr, int arrSize, int target) {
198+
HashMap count[101] = {0};
199+
int countSize = 0;
200+
201+
for (int i = 0; i < arrSize; i++) {
202+
count[arr[i]].key = arr[i];
203+
count[arr[i]].value++;
204+
}
205+
206+
for (int i = 0; i <= 100; i++) {
207+
if (count[i].value > 0) {
208+
count[countSize++] = count[i];
209+
}
210+
}
211+
212+
qsort(count, countSize, sizeof(HashMap), compare);
213+
214+
long result = 0;
215+
216+
for (int i = 0; i < countSize; i++) {
217+
for (int j = i; j < countSize; j++) {
218+
int k = target - count[i].key - count[j].key;
219+
if (k < 0 || k > 100 || count[k].value == 0) continue;
220+
221+
if (count[i].key == count[j].key && count[j].key == k) {
222+
result += count[i].value * (count[i].value - 1) * (count[i].value - 2) / 6;
223+
} else if (count[i].key == count[j].key && count[j].key != k) {
224+
result += count[i].value * (count[i].value - 1) / 2 * count[k].value;
225+
} else if (count[i].key < count[j].key && count[j].key < k) {
226+
result += count[i].value * count[j].value * count[k].value;
227+
}
228+
229+
result %= MOD;
230+
}
231+
}
232+
233+
return result;
234+
}
235+
```
236+
237+
### JavaScript
238+
```javascript
239+
var threeSumMulti = function(arr, target) {
240+
const MOD = 1e9 + 7;
241+
let count = new Map();
242+
243+
for (let num of arr) {
244+
count.set(num, (count.get(num) || 0) + 1);
245+
}
246+
247+
let keys = Array.from(count.keys()).sort((a, b) => a - b);
248+
let result = 0;
249+
250+
for (let i = 0; i < keys.length; i++) {
251+
let x = keys[i];
252+
let T = target - x;
253+
let j = i, k = keys.length - 1;
254+
255+
while (j <= k) {
256+
let y = keys[j], z = keys[k];
257+
if (
258+
259+
y + z < T) {
260+
j++;
261+
} else if (y + z > T) {
262+
k--;
263+
} else {
264+
if (i < j && j < k) {
265+
result += count.get(x) * count.get(y) * count.get(z);
266+
} else if (i === j && j < k) {
267+
result += count.get(x) * (count.get(x) - 1) / 2 * count.get(z);
268+
} else if (i < j && j === k) {
269+
result += count.get(x) * count.get(y) * (count.get(y) - 1) / 2;
270+
} else { // i === j === k
271+
result += count.get(x) * (count.get(x) - 1) * (count.get(x) - 2) / 6;
272+
}
273+
result %= MOD;
274+
j++;
275+
k--;
276+
}
277+
}
278+
}
279+
280+
return result;
281+
};
282+
```
283+
284+
## Step by Step Algorithm
285+
286+
1. **Initialize Variables**: Create a hashmap to count the occurrences of each element in the array.
287+
2. **Count Elements**: Iterate through the array and populate the hashmap with the count of each element.
288+
3. **Sort Keys**: Sort the unique keys from the hashmap.
289+
4. **Iterate Over Pairs**: Use a nested loop to iterate over each pair of elements `(i, j)` and calculate the third element `k` needed to reach the target sum.
290+
5. **Check Existence of k**: Verify if `k` exists in the hashmap.
291+
6. **Count Triplets**: Depending on the values of `i`, `j`, and `k`, count the valid triplets using combinatorics:
292+
- All three elements are the same: Use combination formula `C(count, 3)`.
293+
- Two elements are the same: Use combination formula `C(count, 2) * count`.
294+
- All three elements are different: Multiply their counts directly.
295+
7. **Modulo Operation**: Take the result modulo `10^9 + 7` to avoid overflow.
296+
8. **Return Result**: Return the final count of valid triplets.
297+
298+
## Conclusion
299+
300+
This problem can be efficiently solved using a combination of counting, sorting, and combinatorics. By carefully handling different cases for the triplet elements and using the modulo operation to prevent overflow, we can count the number of valid triplets that sum to the target.

0 commit comments

Comments
 (0)