Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 13ca332

Browse files
feat: add solutions to lc problem: No.1298 (doocs#4457)
No.1298.Maximum Candies You Can Get from Boxes
1 parent 9716c9c commit 13ca332

File tree

8 files changed

+670
-277
lines changed

8 files changed

+670
-277
lines changed

‎solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README.md‎

Lines changed: 232 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,24 @@ tags:
9999

100100
<!-- solution:start -->
101101

102-
### 方法一:BFS
102+
### 方法一:BFS + 哈希集合
103+
104+
题目给定一批盒子,每个盒子可能有状态(开/关)、糖果、钥匙、以及其他盒子。我们的目标是通过初始给定的一些盒子,尽可能多地打开更多盒子,并收集其中的糖果。可以通过获得钥匙来解锁新盒子,通过盒子中嵌套的盒子来获取更多资源。
105+
106+
我们采用 BFS 的方式模拟整个探索过程。
107+
108+
我们用一个队列 $q$ 表示当前可以访问的、**已经开启** 的盒子;用两个集合 $\textit{has}$ 和 $\textit{took}$ 分别记录**我们拥有的所有盒子****已经处理过的盒子**,防止重复。
109+
110+
初始时,将所有 $\textit{initialBoxes}$ 添加到 $\textit{has}$ 中,如果初始盒子状态为开启,立即加入队列 $\textit{q}$ 并累计糖果;
111+
112+
然后进行 BFS,依次从 $\textit{q}$ 中取出盒子:
113+
114+
- 获取盒子中的钥匙 $\textit{keys[box]},ドル将能解锁的盒子加入队列;
115+
- 收集盒子中包含的其他盒子 $\textit{containedBoxes[box]},ドル如果状态是开启的且未处理过,则立即处理;
116+
117+
每个盒子最多处理一次,糖果累计一次,最终返回总糖果数 $\textit{ans}$。
118+
119+
时间复杂度 $O(n),ドル空间复杂度 $O(n),ドル其中 $n$ 是盒子的总数。
103120

104121
<!-- tabs:start -->
105122

@@ -115,25 +132,31 @@ class Solution:
115132
containedBoxes: List[List[int]],
116133
initialBoxes: List[int],
117134
) -> int:
118-
q = deque([i for i in initialBoxes if status[i] == 1])
119-
ans = sum(candies[i] for i in initialBoxes if status[i] == 1)
120-
has = set(initialBoxes)
121-
took = {i for i in initialBoxes if status[i] == 1}
122-
135+
q = deque()
136+
has, took = set(initialBoxes), set()
137+
ans = 0
138+
139+
for box in initialBoxes:
140+
if status[box]:
141+
q.append(box)
142+
took.add(box)
143+
ans += candies[box]
123144
while q:
124-
i = q.popleft()
125-
for k in keys[i]:
126-
status[k] = 1
127-
if k in has and k not in took:
128-
ans += candies[k]
129-
took.add(k)
130-
q.append(k)
131-
for j in containedBoxes[i]:
132-
has.add(j)
133-
if status[j] and j not in took:
134-
ans += candies[j]
135-
took.add(j)
136-
q.append(j)
145+
box = q.popleft()
146+
for k in keys[box]:
147+
if not status[k]:
148+
status[k] = 1
149+
if k in has and k not in took:
150+
q.append(k)
151+
took.add(k)
152+
ans += candies[k]
153+
154+
for b in containedBoxes[box]:
155+
has.add(b)
156+
if status[b] and b not in took:
157+
q.append(b)
158+
took.add(b)
159+
ans += candies[b]
137160
return ans
138161
```
139162

@@ -143,35 +166,36 @@ class Solution:
143166
class Solution {
144167
public int maxCandies(
145168
int[] status, int[] candies, int[][] keys, int[][] containedBoxes, int[] initialBoxes) {
146-
int ans = 0;
147-
int n = status.length;
148-
boolean[] has = new boolean[n];
149-
boolean[] took = new boolean[n];
150169
Deque<Integer> q = new ArrayDeque<>();
151-
for (int i : initialBoxes) {
152-
has[i] = true;
153-
if (status[i] == 1) {
154-
ans += candies[i];
155-
took[i] = true;
156-
q.offer(i);
170+
Set<Integer> has = new HashSet<>();
171+
Set<Integer> took = new HashSet<>();
172+
int ans = 0;
173+
for (int box : initialBoxes) {
174+
has.add(box);
175+
if (status[box] == 1) {
176+
q.offer(box);
177+
took.add(box);
178+
ans += candies[box];
157179
}
158180
}
159181
while (!q.isEmpty()) {
160-
int i = q.poll();
161-
for (int k : keys[i]) {
162-
status[k] = 1;
163-
if (has[k] && !took[k]) {
164-
ans += candies[k];
165-
took[k] = true;
166-
q.offer(k);
182+
int box = q.poll();
183+
for (int k : keys[box]) {
184+
if (status[k] == 0) {
185+
status[k] = 1;
186+
if (has.contains(k) && !took.contains(k)) {
187+
q.offer(k);
188+
took.add(k);
189+
ans += candies[k];
190+
}
167191
}
168192
}
169-
for (int j : containedBoxes[i]) {
170-
has[j] =true;
171-
if (status[j] == 1 && !took[j]) {
172-
ans += candies[j];
173-
took[j] =true;
174-
q.offer(j);
193+
for (int b : containedBoxes[box]) {
194+
has.add(b);
195+
if (status[b] == 1 && !took.contains(b)) {
196+
q.offer(b);
197+
took.add(b);
198+
ans += candies[b];
175199
}
176200
}
177201
}
@@ -185,40 +209,50 @@ class Solution {
185209
```cpp
186210
class Solution {
187211
public:
188-
int maxCandies(vector<int>& status, vector<int>& candies, vector<vector<int>>& keys, vector<vector<int>>& containedBoxes, vector<int>& initialBoxes) {
189-
int ans = 0;
190-
int n = status.size();
191-
vector<bool> has(n);
192-
vector<bool> took(n);
212+
int maxCandies(
213+
vector<int>& status,
214+
vector<int>& candies,
215+
vector<vector<int>>& keys,
216+
vector<vector<int>>& containedBoxes,
217+
vector<int>& initialBoxes) {
193218
queue<int> q;
194-
for (int& i : initialBoxes) {
195-
has[i] = true;
196-
if (status[i]) {
197-
ans += candies[i];
198-
took[i] = true;
199-
q.push(i);
219+
unordered_set<int> has, took;
220+
int ans = 0;
221+
222+
for (int box : initialBoxes) {
223+
has.insert(box);
224+
if (status[box]) {
225+
q.push(box);
226+
took.insert(box);
227+
ans += candies[box];
200228
}
201229
}
230+
202231
while (!q.empty()) {
203-
int i = q.front();
232+
int box = q.front();
204233
q.pop();
205-
for (int k : keys[i]) {
206-
status[k] = 1;
207-
if (has[k] && !took[k]) {
208-
ans += candies[k];
209-
took[k] = true;
210-
q.push(k);
234+
235+
for (int k : keys[box]) {
236+
if (!status[k]) {
237+
status[k] = 1;
238+
if (has.count(k) && !took.count(k)) {
239+
q.push(k);
240+
took.insert(k);
241+
ans += candies[k];
242+
}
211243
}
212244
}
213-
for (int j : containedBoxes[i]) {
214-
has[j] = true;
215-
if (status[j] && !took[j]) {
216-
ans += candies[j];
217-
took[j] = true;
218-
q.push(j);
245+
246+
for (int b : containedBoxes[box]) {
247+
has.insert(b);
248+
if (status[b] && !took.count(b)) {
249+
q.push(b);
250+
took.insert(b);
251+
ans += candies[b];
219252
}
220253
}
221254
}
255+
222256
return ans;
223257
}
224258
};
@@ -227,41 +261,147 @@ public:
227261
#### Go
228262

229263
```go
230-
func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) int {
231-
ans := 0
232-
n := len(status)
233-
has := make([]bool, n)
234-
took := make([]bool, n)
235-
var q []int
236-
for _, i := range initialBoxes {
237-
has[i] = true
238-
if status[i] == 1 {
239-
ans += candies[i]
240-
took[i] = true
241-
q = append(q, i)
264+
func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) (ans int) {
265+
q := []int{}
266+
has := make(map[int]bool)
267+
took := make(map[int]bool)
268+
for _, box := range initialBoxes {
269+
has[box] = true
270+
if status[box] == 1 {
271+
q = append(q, box)
272+
took[box] = true
273+
ans += candies[box]
242274
}
243275
}
244276
for len(q) > 0 {
245-
i := q[0]
277+
box := q[0]
246278
q = q[1:]
247-
for _, k := range keys[i] {
248-
status[k] = 1
249-
if has[k] && !took[k] {
250-
ans += candies[k]
251-
took[k] = true
252-
q = append(q, k)
279+
for _, k := range keys[box] {
280+
if status[k] == 0 {
281+
status[k] = 1
282+
if has[k] && !took[k] {
283+
q = append(q, k)
284+
took[k] = true
285+
ans += candies[k]
286+
}
253287
}
254288
}
255-
for _, j := range containedBoxes[i] {
256-
has[j] = true
257-
if status[j] == 1 && !took[j] {
258-
ans += candies[j]
259-
took[j] = true
260-
q = append(q, j)
289+
for _, b := range containedBoxes[box] {
290+
has[b] = true
291+
if status[b] == 1 && !took[b] {
292+
q = append(q, b)
293+
took[b] = true
294+
ans += candies[b]
261295
}
262296
}
263297
}
264-
return ans
298+
return
299+
}
300+
```
301+
302+
#### TypeScript
303+
304+
```ts
305+
function maxCandies(
306+
status: number[],
307+
candies: number[],
308+
keys: number[][],
309+
containedBoxes: number[][],
310+
initialBoxes: number[],
311+
): number {
312+
const q: number[] = [];
313+
const has: Set<number> = new Set();
314+
const took: Set<number> = new Set();
315+
let ans = 0;
316+
317+
for (const box of initialBoxes) {
318+
has.add(box);
319+
if (status[box] === 1) {
320+
q.push(box);
321+
took.add(box);
322+
ans += candies[box];
323+
}
324+
}
325+
326+
while (q.length > 0) {
327+
const box = q.pop()!;
328+
329+
for (const k of keys[box]) {
330+
if (status[k] === 0) {
331+
status[k] = 1;
332+
if (has.has(k) && !took.has(k)) {
333+
q.push(k);
334+
took.add(k);
335+
ans += candies[k];
336+
}
337+
}
338+
}
339+
340+
for (const b of containedBoxes[box]) {
341+
has.add(b);
342+
if (status[b] === 1 && !took.has(b)) {
343+
q.push(b);
344+
took.add(b);
345+
ans += candies[b];
346+
}
347+
}
348+
}
349+
350+
return ans;
351+
}
352+
```
353+
354+
#### Rust
355+
356+
```rust
357+
use std::collections::{HashSet, VecDeque};
358+
359+
impl Solution {
360+
pub fn max_candies(
361+
mut status: Vec<i32>,
362+
candies: Vec<i32>,
363+
keys: Vec<Vec<i32>>,
364+
contained_boxes: Vec<Vec<i32>>,
365+
initial_boxes: Vec<i32>,
366+
) -> i32 {
367+
let mut q: VecDeque<i32> = VecDeque::new();
368+
let mut has: HashSet<i32> = HashSet::new();
369+
let mut took: HashSet<i32> = HashSet::new();
370+
let mut ans = 0;
371+
372+
for &box_ in &initial_boxes {
373+
has.insert(box_);
374+
if status[box_ as usize] == 1 {
375+
q.push_back(box_);
376+
took.insert(box_);
377+
ans += candies[box_ as usize];
378+
}
379+
}
380+
381+
while let Some(box_) = q.pop_front() {
382+
for &k in &keys[box_ as usize] {
383+
if status[k as usize] == 0 {
384+
status[k as usize] = 1;
385+
if has.contains(&k) && !took.contains(&k) {
386+
q.push_back(k);
387+
took.insert(k);
388+
ans += candies[k as usize];
389+
}
390+
}
391+
}
392+
393+
for &b in &contained_boxes[box_ as usize] {
394+
has.insert(b);
395+
if status[b as usize] == 1 && !took.contains(&b) {
396+
q.push_back(b);
397+
took.insert(b);
398+
ans += candies[b as usize];
399+
}
400+
}
401+
}
402+
403+
ans
404+
}
265405
}
266406
```
267407

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /