Skip to content

Commit 408c8f3

Browse files
Merge pull request youngyangyang04#1917 from StriveDD/master
添加0127.单词接龙的Java版本双向BFS代码,0827.最大人工岛的Java版本,0841.钥匙和房间的Java版本的BFS代码
2 parents 2a9b627 + 2d88a48 commit 408c8f3

File tree

3 files changed

+175
-1
lines changed

3 files changed

+175
-1
lines changed

problems/0127.单词接龙.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* 转换过程中的中间单词必须是字典 wordList 中的单词。
1717
* 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。
1818

19-
 
19+
2020
示例 1:
2121

2222
* 输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
@@ -134,7 +134,70 @@ public int ladderLength(String beginWord, String endWord, List<String> wordList)
134134
}
135135
```
136136

137+
```java
138+
// Java 双向BFS
139+
class Solution {
140+
// 判断单词之间是否之差了一个字母
141+
public boolean isValid(String currentWord, String chooseWord) {
142+
int count = 0;
143+
for (int i = 0; i < currentWord.length(); i++)
144+
if (currentWord.charAt(i) != chooseWord.charAt(i)) ++count;
145+
return count == 1;
146+
}
147+
148+
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
149+
if (!wordList.contains(endWord)) return 0; // 如果 endWord 不在 wordList 中,那么无法成功转换,返回 0
150+
151+
// ansLeft 记录从 beginWord 开始 BFS 时能组成的单词数目
152+
// ansRight 记录从 endWord 开始 BFS 时能组成的单词数目
153+
int ansLeft = 0, ansRight = 0;
154+
155+
// queueLeft 表示从 beginWord 开始 BFS 时使用的队列
156+
// queueRight 表示从 endWord 开始 BFS 时使用的队列
157+
Queue<String> queueLeft = new ArrayDeque<>(), queueRight = new ArrayDeque<>();
158+
queueLeft.add(beginWord);
159+
queueRight.add(endWord);
160+
161+
// 从 beginWord 开始 BFS 时把遍历到的节点存入 hashSetLeft 中
162+
// 从 endWord 开始 BFS 时把遍历到的节点存入 hashSetRight 中
163+
Set<String> hashSetLeft = new HashSet<>(), hashSetRight = new HashSet<>();
164+
hashSetLeft.add(beginWord);
165+
hashSetRight.add(endWord);
166+
167+
// 只要有一个队列为空,说明 beginWord 无法转换到 endWord
168+
while (!queueLeft.isEmpty() && !queueRight.isEmpty()) {
169+
++ansLeft;
170+
int size = queueLeft.size();
171+
for (int i = 0; i < size; i++) {
172+
String currentWord = queueLeft.poll();
173+
// 只要 hashSetRight 中存在 currentWord,说明从 currentWord 可以转换到 endWord
174+
if (hashSetRight.contains(currentWord)) return ansRight + ansLeft;
175+
for (String chooseWord : wordList) {
176+
if (hashSetLeft.contains(chooseWord) || !isValid(currentWord, chooseWord)) continue;
177+
hashSetLeft.add(chooseWord);
178+
queueLeft.add(chooseWord);
179+
}
180+
}
181+
++ansRight;
182+
size = queueRight.size();
183+
for (int i = 0; i < size; i++) {
184+
String currentWord = queueRight.poll();
185+
// 只要 hashSetLeft 中存在 currentWord,说明从 currentWord 可以转换到 beginWord
186+
if (hashSetLeft.contains(currentWord)) return ansLeft + ansRight;
187+
for (String chooseWord : wordList) {
188+
if (hashSetRight.contains(chooseWord) || !isValid(currentWord, chooseWord)) continue;
189+
hashSetRight.add(chooseWord);
190+
queueRight.add(chooseWord);
191+
}
192+
}
193+
}
194+
return 0;
195+
}
196+
}
197+
```
198+
137199
## Python
200+
138201
```
139202
class Solution:
140203
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
@@ -301,3 +364,4 @@ function diffonechar(word1: string, word2: string): boolean {
301364
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
302365
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
303366
</a>
367+

problems/0827.最大人工岛.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,71 @@ public:
219219
};
220220
```
221221

222+
# 其他语言版本
223+
224+
## Java
225+
226+
```Java
227+
class Solution {
228+
private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 四个方向
229+
230+
/**
231+
* @param grid 矩阵数组
232+
* @param row 当前遍历的节点的行号
233+
* @param col 当前遍历的节点的列号
234+
* @param mark 当前区域的标记
235+
* @return 返回当前区域内 1 的数量
236+
*/
237+
public int dfs(int[][] grid, int row, int col, int mark) {
238+
int ans = 0;
239+
grid[row][col] = mark;
240+
for (int[] current: position) {
241+
int curRow = row + current[0], curCol = col + current[1];
242+
if (curRow < 0 || curRow >= grid.length || curCol < 0 || curCol >= grid.length) continue; // 越界
243+
if (grid[curRow][curCol] == 1)
244+
ans += 1 + dfs(grid, curRow, curCol, mark);
245+
}
246+
return ans;
247+
}
248+
249+
public int largestIsland(int[][] grid) {
250+
int ans = Integer.MIN_VALUE, size = grid.length, mark = 2;
251+
Map<Integer, Integer> getSize = new HashMap<>();
252+
for (int row = 0; row < size; row++) {
253+
for (int col = 0; col < size; col++) {
254+
if (grid[row][col] == 1) {
255+
int areaSize = 1 + dfs(grid, row, col, mark);
256+
getSize.put(mark++, areaSize);
257+
}
258+
}
259+
}
260+
for (int row = 0; row < size; row++) {
261+
for (int col = 0; col < size; col++) {
262+
// 当前位置如果不是 0 那么直接跳过,因为我们只能把 0 变成 1
263+
if (grid[row][col] != 0) continue;
264+
Set<Integer> hashSet = new HashSet<>(); // 防止同一个区域被重复计算
265+
// 计算从当前位置开始获取的 1 的数量,初始化 1 是因为把当前位置的 0 转换成了 1
266+
int curSize = 1;
267+
for (int[] current: position) {
268+
int curRow = row + current[0], curCol = col + current[1];
269+
if (curRow < 0 || curRow >= grid.length || curCol < 0 || curCol >= grid.length) continue;
270+
int curMark = grid[curRow][curCol]; // 获取对应位置的标记
271+
// 如果标记存在 hashSet 中说明该标记被记录过一次,如果不存在 getSize 中说明该标记是无效标记(此时 curMark = 0)
272+
if (hashSet.contains(curMark) || !getSize.containsKey(curMark)) continue;
273+
hashSet.add(curMark);
274+
curSize += getSize.get(curMark);
275+
}
276+
ans = Math.max(ans, curSize);
277+
}
278+
}
279+
// 当 ans == Integer.MIN_VALUE 说明矩阵数组中不存在 0,全都是有效区域,返回数组大小即可
280+
return ans == Integer.MIN_VALUE ? size * size : ans;
281+
}
282+
}
283+
```
284+
222285
<p align="center">
223286
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
224287
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
225288
</a>
289+

problems/0841.钥匙和房间.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,52 @@ class Solution {
275275
}
276276
```
277277

278+
```Java
279+
// 广度优先搜索
280+
class Solution {
281+
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
282+
boolean[] visited = new boolean[rooms.size()]; // 用一个 visited 数据记录房间是否被访问
283+
visited[0] = true;
284+
Queue<Integer> queue = new ArrayDeque<>();
285+
queue.add(0); // 第 0 个房间标记为已访问
286+
while (!queue.isEmpty()) {
287+
int curKey = queue.poll();
288+
for (int key: rooms.get(curKey)) {
289+
if (visited[key]) continue;
290+
visited[key] = true;
291+
queue.add(key);
292+
}
293+
}
294+
for (boolean key: visited)
295+
if (!key) return false;
296+
return true;
297+
}
298+
}
299+
```
300+
301+
```java
302+
// 广度优先遍历(时间优化)
303+
class Solution {
304+
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
305+
int count = 1; // 用来记录可以被访问的房间数目,因为初始状态下 0 号房间可以被访问,所以置为 1
306+
boolean[] visited = new boolean[rooms.size()]; // 用一个 visited 数据记录房间是否被访问
307+
visited[0] = true; // 第 0 个房间标记为已访问
308+
Queue<Integer> queue = new ArrayDeque<>();
309+
queue.add(0);
310+
while (!queue.isEmpty()) {
311+
int curKey = queue.poll();
312+
for (int key: rooms.get(curKey)) {
313+
if (visited[key]) continue;
314+
++count; // 每访问一个访问房间就让 count 加 1
315+
visited[key] = true;
316+
queue.add(key);
317+
}
318+
}
319+
return count == rooms.size(); // 如果 count 等于房间数目,表示能进入所有房间,反之不能
320+
}
321+
}
322+
```
323+
278324
### python3
279325

280326
```python

0 commit comments

Comments
 (0)