Skip to content

Commit b820022

Browse files
committed
feat: add solutions to lc problem: No.1711
No.1711.Count Good Meals
1 parent e21e1a8 commit b820022

File tree

6 files changed

+260
-239
lines changed

6 files changed

+260
-239
lines changed

solution/1700-1799/1711.Count Good Meals/README.md

Lines changed: 112 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,25 @@
4343

4444
## 解法
4545

46-
**方法一:哈希表**
46+
**方法一:哈希表 + 枚举二的幂**
4747

48-
用最暴力的方法枚举每对元素肯定会超时,可以用哈希表优化对**之前元素出现次数**的查询
48+
根据题意,我们需要统计数组中两个数的和为 $2$ 的幂的组合数。直接暴力枚举所有的组合数,时间复杂度为 $O(n^2)$ ,肯定会超时
4949

50-
**方法二:枚举二的幂**
50+
我们可以遍历数组,用哈希表 $cnt$ 维护数组中每个元素 $d$ 出现的次数。
5151

52-
用哈希表 `cnt` 记录数组中每个元素出现的次数
52+
对于每个元素,我们从小到大枚举二的幂次方 $s$ 作为两数之和,将哈希表中 $s - d$ 出现的次数累加到答案中。然后将当前元素 $d$ 出现的次数加一
5353

54-
枚举二的幂次方作为两数之和 `s`,然后枚举其中一个数 `a`,判断 `s-a` 是否出现在哈希表 `cnt` 中。若出现,判断 `a``b` 是否相等,是则答案累加 `cnt[a] * (cnt[a]-1)`,否则答案累加 `cnt[a] * cnt[b]`
54+
遍历结束后,返回答案即可
5555

56-
由于每个 `a``b` 会重复枚举,因此最后答案需要除以 `2`。注意取模操作
56+
时间复杂度 $O(n\times \log M)$,其中 $n$ 是数组 `deliciousness` 的长度,而 $M$ 是元素的上限,对于本题,上限 $M=2^{20}$
5757

58-
时间复杂度 $O(n\log C)$,其中 $n$ 是数组 `deliciousness` 的长度,而 $C$ 是元素的上限,对于本题,上限 $C=2^{20}$。
58+
我们也可以先用哈希表 $cnt$ 统计数组中每个元素出现的次数。
59+
60+
然后从小到大枚举二的幂次方 $s$ 作为两数之和,对于每个 $s$,遍历哈希表每个键值对 $(a, m)$,如果 $s - a$ 也在哈希表中,且 $s - a \neq a$,则答案加上 $m \times cnt[s - a]$;如果 $s - a = a$,则答案加上 $m \times (m - 1)$。
61+
62+
最后,将答案除以 $2$ 之后,模 $10^9 + 7$,返回即可。
63+
64+
时间复杂度与上面的方法相同。
5965

6066
<!-- 这里可写通用的实现逻辑 -->
6167

@@ -68,33 +74,30 @@
6874
```python
6975
class Solution:
7076
def countPairs(self, deliciousness: List[int]) -> int:
71-
mod = 1000000007
72-
limit = max(deliciousness) * 2
73-
pairs = 0
74-
freq = defaultdict(int)
77+
mod = 10**9 + 7
78+
mx = max(deliciousness) << 1
79+
cnt = Counter()
80+
ans = 0
7581
for d in deliciousness:
76-
target = 1
77-
while target <= limit:
78-
pairs = (pairs + freq[target - d]) % mod
79-
target = target << 1
80-
freq[d] += 1
81-
return pairs
82+
s = 1
83+
while s <= mx:
84+
ans = (ans + cnt[s - d]) % mod
85+
s <<= 1
86+
cnt[d] += 1
87+
return ans
8288
```
8389

8490
```python
8591
class Solution:
8692
def countPairs(self, deliciousness: List[int]) -> int:
93+
mod = 10**9 + 7
8794
cnt = Counter(deliciousness)
8895
ans = 0
89-
mod = 10**9 + 7
9096
for i in range(22):
9197
s = 1 << i
9298
for a, m in cnt.items():
9399
if (b := s - a) in cnt:
94-
if a == b:
95-
ans += m * (m - 1)
96-
else:
97-
ans += m * cnt[b]
100+
ans += m * (m - 1) if a == b else m * cnt[b]
98101
return (ans >> 1) % mod
99102
```
100103

@@ -104,21 +107,19 @@ class Solution:
104107

105108
```java
106109
class Solution {
107-
108-
private static final int MOD = 1000000007;
110+
private static final int MOD = (int) 1e9 + 7;
109111

110112
public int countPairs(int[] deliciousness) {
111-
int limit = Arrays.stream(deliciousness).max().getAsInt() * 2;
112-
int pairs = 0;
113-
Map<Integer, Integer> freq = new HashMap<>();
113+
int mx = Arrays.stream(deliciousness).max().getAsInt() << 1;
114+
int ans = 0;
115+
Map<Integer, Integer> cnt = new HashMap<>();
114116
for (int d : deliciousness) {
115-
for (int sum = 1; sum <= limit; sum <<= 1) {
116-
int count = freq.getOrDefault(sum - d, 0);
117-
pairs = (pairs + count) % MOD;
117+
for (int s = 1; s <= mx; s <<= 1) {
118+
ans = (ans + cnt.getOrDefault(s - d, 0)) % MOD;
118119
}
119-
freq.merge(d, 1, Integer::sum);
120+
cnt.merge(d, 1, Integer::sum);
120121
}
121-
return pairs;
122+
return ans;
122123
}
123124
}
124125
```
@@ -129,8 +130,8 @@ class Solution {
129130

130131
public int countPairs(int[] deliciousness) {
131132
Map<Integer, Integer> cnt = new HashMap<>();
132-
for (int v : deliciousness) {
133-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
133+
for (int d : deliciousness) {
134+
cnt.put(d, cnt.getOrDefault(d, 0) + 1);
134135
}
135136
long ans = 0;
136137
for (int i = 0; i < 22; ++i) {
@@ -141,11 +142,7 @@ class Solution {
141142
if (!cnt.containsKey(b)) {
142143
continue;
143144
}
144-
if (a == b) {
145-
ans += (long) m * (m - 1);
146-
} else {
147-
ans += (long) m * cnt.get(b);
148-
}
145+
ans += 1L * m * (a == b ? m - 1 : cnt.get(b));
149146
}
150147
}
151148
ans >>= 1;
@@ -154,87 +151,104 @@ class Solution {
154151
}
155152
```
156153

157-
### **Go**
158-
159-
```go
160-
const mod int = 1e9 + 7
161-
162-
func countPairs(deliciousness []int) int {
163-
limit := 0
164-
for _, d := range deliciousness {
165-
limit = max(limit, d)
166-
}
167-
limit *= 2
168-
pairs := 0
169-
freq := make(map[int]int)
170-
for _, d := range deliciousness {
171-
for sum := 1; sum <= limit; sum <<= 1 {
172-
pairs = (pairs + freq[sum-d]) % mod
173-
}
174-
freq[d]++
175-
}
176-
return pairs
177-
}
154+
### **C++**
178155

179-
func max(x, y int) int {
180-
if x > y {
181-
return x
182-
}
183-
return y
184-
}
185-
```
156+
```cpp
157+
class Solution {
158+
public:
159+
const int mod = 1e9 + 7;
186160

187-
```go
188-
func countPairs(deliciousness []int) int {
189-
cnt := map[int]int{}
190-
for _, v := range deliciousness {
191-
cnt[v]++
192-
}
193-
ans := 0
194-
mod := int(1e9) + 7
195-
for i := 0; i < 22; i++ {
196-
s := 1 << i
197-
for a, m := range cnt {
198-
b := s - a
199-
if n, ok := cnt[b]; ok {
200-
if a == b {
201-
ans += m * (m - 1)
202-
} else {
203-
ans += m * n
204-
}
205-
}
206-
}
207-
}
208-
ans >>= 1
209-
return ans % mod
210-
}
161+
int countPairs(vector<int>& deliciousness) {
162+
int mx = *max_element(deliciousness.begin(), deliciousness.end()) << 1;
163+
unordered_map<int, int> cnt;
164+
int ans = 0;
165+
for (auto& d : deliciousness) {
166+
for (int s = 1; s <= mx; s <<= 1) {
167+
ans = (ans + cnt[s - d]) % mod;
168+
}
169+
++cnt[d];
170+
}
171+
return ans;
172+
}
173+
};
211174
```
212175

213-
### **C++**
214-
215176
```cpp
216177
class Solution {
217178
public:
179+
const int mod = 1e9 + 7;
180+
218181
int countPairs(vector<int>& deliciousness) {
219182
unordered_map<int, int> cnt;
220-
for (int v : deliciousness) ++cnt[v];
183+
for (int& d : deliciousness) ++cnt[d];
221184
long long ans = 0;
222185
for (int i = 0; i < 22; ++i) {
223186
int s = 1 << i;
224187
for (auto& [a, m] : cnt) {
225188
int b = s - a;
226189
if (!cnt.count(b)) continue;
227-
if (a == b) ans += 1ll * m * (m - 1);
228-
else ans += 1ll * m * cnt[b];
190+
ans += 1ll * m * (a == b ? (m - 1) : cnt[b]);
229191
}
230192
}
231193
ans >>= 1;
232-
int mod = 1e9 + 7;
233-
return (int) (ans % mod);
194+
return ans % mod;
234195
}
235196
};
236197
```
237198

199+
### **Go**
200+
201+
```go
202+
func countPairs(deliciousness []int) (ans int) {
203+
mx := 0
204+
for _, d := range deliciousness {
205+
mx = max(mx, d)
206+
}
207+
mx <<= 1
208+
const mod int = 1e9 + 7
209+
cnt := map[int]int{}
210+
for _, d := range deliciousness {
211+
for s := 1; s <= mx; s <<= 1 {
212+
ans = (ans + cnt[s-d]) % mod
213+
}
214+
cnt[d]++
215+
}
216+
return
217+
}
218+
219+
func max(a, b int) int {
220+
if a > b {
221+
return a
222+
}
223+
return b
224+
}
225+
```
226+
227+
```go
228+
func countPairs(deliciousness []int) (ans int) {
229+
cnt := map[int]int{}
230+
for _, d := range deliciousness {
231+
cnt[d]++
232+
}
233+
const mod int = 1e9 + 7
234+
for i := 0; i < 22; i++ {
235+
s := 1 << i
236+
for a, m := range cnt {
237+
b := s - a
238+
if n, ok := cnt[b]; ok {
239+
if a == b {
240+
ans += m * (m - 1)
241+
} else {
242+
ans += m * n
243+
}
244+
}
245+
}
246+
}
247+
ans >>= 1
248+
return ans % mod
249+
}
250+
```
251+
238252
### **...**
239253

240254
```

0 commit comments

Comments
 (0)