Skip to content

Commit 55a3d0a

Browse files
authored
feat: add solutions to lc problem: No.0923 (#2596)
No.0923.3Sum With Multiplicity
1 parent a7e034d commit 55a3d0a

File tree

7 files changed

+163
-130
lines changed

7 files changed

+163
-130
lines changed

solution/0900-0999/0923.3Sum With Multiplicity/README.md

+57-45
Original file line numberDiff line numberDiff line change
@@ -50,79 +50,73 @@ arr[i] = 1, arr[j] = arr[k] = 2 出现 12 次:
5050

5151
## 解法
5252

53-
### 方法一:枚举
53+
### 方法一:计数 + 枚举
5454

55-
我们先用一个长度为 $101$ 的数组 `cnt` 记录数组 `arr` 中每个元素出现的次数
55+
我们可以用一个哈希表或者一个长度为 $101$ 的数组 $cnt$ 统计数组 $arr$ 中每个元素的出现次数
5656

57-
然后枚举数组 `arr` 中的元素作为三元组的第二个元素 $b$,先让 `cnt` 减去其中一个 $b$。接着从数组 `arr` 的开头开始枚举第一个元素 $a$,那么第三个元素 $c$ 为 $target - a - b$。如果 $c$ 的值在数组 `cnt` 的范围内,那么答案加上 $cnt[c]$。
57+
然后,我们枚举数组 $arr$ 中的每个元素 $arr[j]$,先将 $cnt[arr[j]]$ 减一,然后再枚举 $arr[j]$ 之前的元素 $arr[i]$,计算 $c = target - arr[i] - arr[j]$,如果 $c$ 在 $[0, 100]$ 的范围内,那么答案就加上 $cnt[c]$,最后返回答案
5858

59-
注意答案的取模操作
59+
注意,这里的答案可能会超过 ${10}^9 + 7$,所以在每次加法操作后都要取模
6060

61-
时间复杂度 $O(n^2)$,空间复杂度 $O(C)$。其中 $n$ 为数组 `arr` 的长度;而 $C$ 为数组 `cnt` 的长度,本题中 $C = 101$。
61+
时间复杂度 $O(n^2)$,其中 $n$ 为数组 $arr$ 的长度。空间复杂度 $O(C)$,其中 $C$ 为数组 $arr$ 中元素的最大值,本题中 $C = 100$。
6262

6363
<!-- tabs:start -->
6464

6565
```python
6666
class Solution:
6767
def threeSumMulti(self, arr: List[int], target: int) -> int:
68+
mod = 10**9 + 7
6869
cnt = Counter(arr)
6970
ans = 0
70-
mod = 10**9 + 7
7171
for j, b in enumerate(arr):
7272
cnt[b] -= 1
73-
for i in range(j):
74-
a = arr[i]
73+
for a in arr[:j]:
7574
c = target - a - b
7675
ans = (ans + cnt[c]) % mod
7776
return ans
7877
```
7978

8079
```java
8180
class Solution {
82-
private static final int MOD = (int) 1e9 + 7;
83-
8481
public int threeSumMulti(int[] arr, int target) {
82+
final int mod = (int) 1e9 + 7;
8583
int[] cnt = new int[101];
86-
for (int v : arr) {
87-
++cnt[v];
84+
for (int x : arr) {
85+
++cnt[x];
8886
}
89-
long ans = 0;
90-
for (int j = 0; j < arr.length; ++j) {
91-
int b = arr[j];
92-
--cnt[b];
87+
int n = arr.length;
88+
int ans = 0;
89+
for (int j = 0; j < n; ++j) {
90+
--cnt[arr[j]];
9391
for (int i = 0; i < j; ++i) {
94-
int a = arr[i];
95-
int c = target - a - b;
96-
if (c >= 0 && c <= 100) {
97-
ans = (ans + cnt[c]) % MOD;
92+
int c = target - arr[i] - arr[j];
93+
if (c >= 0 && c < cnt.length) {
94+
ans = (ans + cnt[c]) % mod;
9895
}
9996
}
10097
}
101-
return (int) ans;
98+
return ans;
10299
}
103100
}
104101
```
105102

106103
```cpp
107104
class Solution {
108105
public:
109-
const int mod = 1e9 + 7;
110-
111106
int threeSumMulti(vector<int>& arr, int target) {
112-
int cnt[101] = {0};
113-
for (int& v : arr) {
114-
++cnt[v];
107+
const int mod = 1e9 + 7;
108+
int cnt[101]{};
109+
for (int x : arr) {
110+
++cnt[x];
115111
}
116-
long ans = 0;
117-
for (int j = 0; j < arr.size(); ++j) {
118-
int b = arr[j];
119-
--cnt[b];
112+
int n = arr.size();
113+
int ans = 0;
114+
for (int j = 0; j < n; ++j) {
115+
--cnt[arr[j]];
120116
for (int i = 0; i < j; ++i) {
121-
int a = arr[i];
122-
int c = target - a - b;
117+
int c = target - arr[i] - arr[j];
123118
if (c >= 0 && c <= 100) {
124-
ans += cnt[c];
125-
ans %= mod;
119+
ans = (ans + cnt[c]) % mod;
126120
}
127121
}
128122
}
@@ -132,25 +126,43 @@ public:
132126
```
133127
134128
```go
135-
func threeSumMulti(arr []int, target int) int {
129+
func threeSumMulti(arr []int, target int) (ans int) {
136130
const mod int = 1e9 + 7
137131
cnt := [101]int{}
138-
for _, v := range arr {
139-
cnt[v]++
132+
for _, x := range arr {
133+
cnt[x]++
140134
}
141-
ans := 0
142135
for j, b := range arr {
143136
cnt[b]--
144-
for i := 0; i < j; i++ {
145-
a := arr[i]
146-
c := target - a - b
147-
if c >= 0 && c <= 100 {
148-
ans += cnt[c]
149-
ans %= mod
137+
for _, a := range arr[:j] {
138+
if c := target - a - b; c >= 0 && c < len(cnt) {
139+
ans = (ans + cnt[c]) % mod
150140
}
151141
}
152142
}
153-
return ans
143+
return
144+
}
145+
```
146+
147+
```ts
148+
function threeSumMulti(arr: number[], target: number): number {
149+
const mod = 10 ** 9 + 7;
150+
const cnt: number[] = Array(101).fill(0);
151+
for (const x of arr) {
152+
++cnt[x];
153+
}
154+
let ans = 0;
155+
const n = arr.length;
156+
for (let j = 0; j < n; ++j) {
157+
--cnt[arr[j]];
158+
for (let i = 0; i < j; ++i) {
159+
const c = target - arr[i] - arr[j];
160+
if (c >= 0 && c < cnt.length) {
161+
ans = (ans + cnt[c]) % mod;
162+
}
163+
}
164+
}
165+
return ans;
154166
}
155167
```
156168

solution/0900-0999/0923.3Sum With Multiplicity/README_EN.md

+57-45
Original file line numberDiff line numberDiff line change
@@ -54,79 +54,73 @@ and two 2s from [2,2,2,2] in 6 ways.
5454

5555
## Solutions
5656

57-
### Solution 1: Enumeration
57+
### Solution 1: Counting + Enumeration
5858

59-
First, we use an array `cnt` of length $101$ to record the number of occurrences of each element in the array `arr`.
59+
We can use a hash table or an array $cnt$ of length $101$ to count the occurrence of each element in the array $arr$.
6060

61-
Then, we enumerate the elements in the array `arr` as the second element $b$ of the triplet, and first subtract one $b$ from `cnt`. Then, starting from the beginning of the array `arr`, we enumerate the first element $a$, and the third element $c$ is $target - a - b$. If the value of $c$ is within the range of the array `cnt`, then the answer is increased by $cnt[c]$.
61+
Then, we enumerate each element $arr[j]$ in the array $arr$, first subtract one from $cnt[arr[j]]$, and then enumerate the elements $arr[i]$ before $arr[j]$, calculate $c = target - arr[i] - arr[j]$. If $c$ is in the range of $[0, 100]$, then the answer is increased by $cnt[c]$, and finally return the answer.
6262

63-
Note the modulo operation of the answer.
63+
Note that the answer may exceed ${10}^9 + 7$, so take the modulus after each addition operation.
6464

65-
The time complexity is $O(n^2)$, and the space complexity is $O(C)$. Where $n$ is the length of the array `arr`; and $C$ is the length of the array `cnt`, in this problem $C = 101$.
65+
The time complexity is $O(n^2)$, where $n$ is the length of the array $arr$. The space complexity is $O(C)$, where $C$ is the maximum value of the elements in the array $arr$, in this problem $C = 100$.
6666

6767
<!-- tabs:start -->
6868

6969
```python
7070
class Solution:
7171
def threeSumMulti(self, arr: List[int], target: int) -> int:
72+
mod = 10**9 + 7
7273
cnt = Counter(arr)
7374
ans = 0
74-
mod = 10**9 + 7
7575
for j, b in enumerate(arr):
7676
cnt[b] -= 1
77-
for i in range(j):
78-
a = arr[i]
77+
for a in arr[:j]:
7978
c = target - a - b
8079
ans = (ans + cnt[c]) % mod
8180
return ans
8281
```
8382

8483
```java
8584
class Solution {
86-
private static final int MOD = (int) 1e9 + 7;
87-
8885
public int threeSumMulti(int[] arr, int target) {
86+
final int mod = (int) 1e9 + 7;
8987
int[] cnt = new int[101];
90-
for (int v : arr) {
91-
++cnt[v];
88+
for (int x : arr) {
89+
++cnt[x];
9290
}
93-
long ans = 0;
94-
for (int j = 0; j < arr.length; ++j) {
95-
int b = arr[j];
96-
--cnt[b];
91+
int n = arr.length;
92+
int ans = 0;
93+
for (int j = 0; j < n; ++j) {
94+
--cnt[arr[j]];
9795
for (int i = 0; i < j; ++i) {
98-
int a = arr[i];
99-
int c = target - a - b;
100-
if (c >= 0 && c <= 100) {
101-
ans = (ans + cnt[c]) % MOD;
96+
int c = target - arr[i] - arr[j];
97+
if (c >= 0 && c < cnt.length) {
98+
ans = (ans + cnt[c]) % mod;
10299
}
103100
}
104101
}
105-
return (int) ans;
102+
return ans;
106103
}
107104
}
108105
```
109106

110107
```cpp
111108
class Solution {
112109
public:
113-
const int mod = 1e9 + 7;
114-
115110
int threeSumMulti(vector<int>& arr, int target) {
116-
int cnt[101] = {0};
117-
for (int& v : arr) {
118-
++cnt[v];
111+
const int mod = 1e9 + 7;
112+
int cnt[101]{};
113+
for (int x : arr) {
114+
++cnt[x];
119115
}
120-
long ans = 0;
121-
for (int j = 0; j < arr.size(); ++j) {
122-
int b = arr[j];
123-
--cnt[b];
116+
int n = arr.size();
117+
int ans = 0;
118+
for (int j = 0; j < n; ++j) {
119+
--cnt[arr[j]];
124120
for (int i = 0; i < j; ++i) {
125-
int a = arr[i];
126-
int c = target - a - b;
121+
int c = target - arr[i] - arr[j];
127122
if (c >= 0 && c <= 100) {
128-
ans += cnt[c];
129-
ans %= mod;
123+
ans = (ans + cnt[c]) % mod;
130124
}
131125
}
132126
}
@@ -136,25 +130,43 @@ public:
136130
```
137131
138132
```go
139-
func threeSumMulti(arr []int, target int) int {
133+
func threeSumMulti(arr []int, target int) (ans int) {
140134
const mod int = 1e9 + 7
141135
cnt := [101]int{}
142-
for _, v := range arr {
143-
cnt[v]++
136+
for _, x := range arr {
137+
cnt[x]++
144138
}
145-
ans := 0
146139
for j, b := range arr {
147140
cnt[b]--
148-
for i := 0; i < j; i++ {
149-
a := arr[i]
150-
c := target - a - b
151-
if c >= 0 && c <= 100 {
152-
ans += cnt[c]
153-
ans %= mod
141+
for _, a := range arr[:j] {
142+
if c := target - a - b; c >= 0 && c < len(cnt) {
143+
ans = (ans + cnt[c]) % mod
154144
}
155145
}
156146
}
157-
return ans
147+
return
148+
}
149+
```
150+
151+
```ts
152+
function threeSumMulti(arr: number[], target: number): number {
153+
const mod = 10 ** 9 + 7;
154+
const cnt: number[] = Array(101).fill(0);
155+
for (const x of arr) {
156+
++cnt[x];
157+
}
158+
let ans = 0;
159+
const n = arr.length;
160+
for (let j = 0; j < n; ++j) {
161+
--cnt[arr[j]];
162+
for (let i = 0; i < j; ++i) {
163+
const c = target - arr[i] - arr[j];
164+
if (c >= 0 && c < cnt.length) {
165+
ans = (ans + cnt[c]) % mod;
166+
}
167+
}
168+
}
169+
return ans;
158170
}
159171
```
160172

solution/0900-0999/0923.3Sum With Multiplicity/Solution.cpp

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
class Solution {
22
public:
3-
const int mod = 1e9 + 7;
4-
53
int threeSumMulti(vector<int>& arr, int target) {
6-
int cnt[101] = {0};
7-
for (int& v : arr) {
8-
++cnt[v];
4+
const int mod = 1e9 + 7;
5+
int cnt[101]{};
6+
for (int x : arr) {
7+
++cnt[x];
98
}
10-
long ans = 0;
11-
for (int j = 0; j < arr.size(); ++j) {
12-
int b = arr[j];
13-
--cnt[b];
9+
int n = arr.size();
10+
int ans = 0;
11+
for (int j = 0; j < n; ++j) {
12+
--cnt[arr[j]];
1413
for (int i = 0; i < j; ++i) {
15-
int a = arr[i];
16-
int c = target - a - b;
14+
int c = target - arr[i] - arr[j];
1715
if (c >= 0 && c <= 100) {
18-
ans += cnt[c];
19-
ans %= mod;
16+
ans = (ans + cnt[c]) % mod;
2017
}
2118
}
2219
}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
func threeSumMulti(arr []int, target int) int {
1+
func threeSumMulti(arr []int, target int) (ans int) {
22
const mod int = 1e9 + 7
33
cnt := [101]int{}
4-
for _, v := range arr {
5-
cnt[v]++
4+
for _, x := range arr {
5+
cnt[x]++
66
}
7-
ans := 0
87
for j, b := range arr {
98
cnt[b]--
10-
for i := 0; i < j; i++ {
11-
a := arr[i]
12-
c := target - a - b
13-
if c >= 0 && c <= 100 {
14-
ans += cnt[c]
15-
ans %= mod
9+
for _, a := range arr[:j] {
10+
if c := target - a - b; c >= 0 && c < len(cnt) {
11+
ans = (ans + cnt[c]) % mod
1612
}
1713
}
1814
}
19-
return ans
15+
return
2016
}

0 commit comments

Comments
 (0)