Skip to content

Commit 65e8658

Browse files
Merge pull request youngyangyang04#2629 from learnerInTheFirstStage/master
更新 0104.建造最大岛屿 DFS解法Java版
2 parents c6635bb + ef99b46 commit 65e8658

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

problems/kamacoder/0103.水流问题.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,78 @@ for (int j = 0; j < m; j++) {
281281
## 其他语言版本
282282

283283
### Java
284+
```Java
285+
public class Main {
286+
287+
// 采用 DFS 进行搜索
288+
public static void dfs(int[][] heights, int x, int y, boolean[][] visited, int preH) {
289+
// 遇到边界或者访问过的点,直接返回
290+
if (x < 0 || x >= heights.length || y < 0 || y >= heights[0].length || visited[x][y]) return;
291+
// 不满足水流入条件的直接返回
292+
if (heights[x][y] < preH) return;
293+
// 满足条件,设置为true,表示可以从边界到达此位置
294+
visited[x][y] = true;
295+
296+
// 向下一层继续搜索
297+
dfs(heights, x + 1, y, visited, heights[x][y]);
298+
dfs(heights, x - 1, y, visited, heights[x][y]);
299+
dfs(heights, x, y + 1, visited, heights[x][y]);
300+
dfs(heights, x, y - 1, visited, heights[x][y]);
301+
}
302+
303+
public static void main(String[] args) {
304+
Scanner sc = new Scanner(System.in);
305+
int m = sc.nextInt();
306+
int n = sc.nextInt();
307+
308+
int[][] heights = new int[m][n];
309+
for (int i = 0; i < m; i++) {
310+
for (int j = 0; j < n; j++) {
311+
heights[i][j] = sc.nextInt();
312+
}
313+
}
314+
315+
// 初始化两个二位boolean数组,代表两个边界
316+
boolean[][] pacific = new boolean[m][n];
317+
boolean[][] atlantic = new boolean[m][n];
318+
319+
// 从左右边界出发进行DFS
320+
for (int i = 0; i < m; i++) {
321+
dfs(heights, i, 0, pacific, Integer.MIN_VALUE);
322+
dfs(heights, i, n - 1, atlantic, Integer.MIN_VALUE);
323+
}
324+
325+
// 从上下边界出发进行DFS
326+
for (int j = 0; j < n; j++) {
327+
dfs(heights, 0, j, pacific, Integer.MIN_VALUE);
328+
dfs(heights, m - 1, j, atlantic, Integer.MIN_VALUE);
329+
}
330+
331+
// 当两个边界二维数组在某个位置都为true时,符合题目要求
332+
List<List<Integer>> res = new ArrayList<>();
333+
for (int i = 0; i < m; i++) {
334+
for (int j = 0; j < n; j++) {
335+
if (pacific[i][j] && atlantic[i][j]) {
336+
res.add(Arrays.asList(i, j));
337+
}
338+
}
339+
}
340+
341+
// 打印结果
342+
for (List<Integer> list : res) {
343+
for (int k = 0; k < list.size(); k++) {
344+
if (k == 0) {
345+
System.out.print(list.get(k) + " ");
346+
} else {
347+
System.out.print(list.get(k));
348+
}
349+
}
350+
System.out.println();
351+
}
352+
}
353+
}
354+
355+
```
284356

285357
### Python
286358

problems/kamacoder/0104.建造最大岛屿.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,111 @@ int main() {
258258
## 其他语言版本
259259

260260
### Java
261+
```Java
262+
public class Main {
263+
// 该方法采用 DFS
264+
// 定义全局变量
265+
// 记录每次每个岛屿的面积
266+
static int count;
267+
// 对每个岛屿进行标记
268+
static int mark;
269+
// 定义二维数组表示四个方位
270+
static int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
271+
272+
// DFS 进行搜索,将每个岛屿标记为不同的数字
273+
public static void dfs(int[][] grid, int x, int y, boolean[][] visited) {
274+
// 当遇到边界,直接return
275+
if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length) return;
276+
// 遇到已经访问过的或者遇到海水,直接返回
277+
if (visited[x][y] || grid[x][y] == 0) return;
278+
279+
visited[x][y] = true;
280+
count++;
281+
grid[x][y] = mark;
282+
283+
// 继续向下层搜索
284+
dfs(grid, x, y + 1, visited);
285+
dfs(grid, x, y - 1, visited);
286+
dfs(grid, x + 1, y, visited);
287+
dfs(grid, x - 1, y, visited);
288+
}
289+
290+
public static void main (String[] args) {
291+
// 接收输入
292+
Scanner sc = new Scanner(System.in);
293+
int m = sc.nextInt();
294+
int n = sc.nextInt();
295+
296+
int[][] grid = new int[m][n];
297+
for (int i = 0; i < m; i++) {
298+
for (int j = 0; j < n; j++) {
299+
grid[i][j] = sc.nextInt();
300+
}
301+
}
302+
303+
// 初始化mark变量,从2开始(区别于0水,1岛屿)
304+
mark = 2;
305+
306+
// 定义二位boolean数组记录该位置是否被访问
307+
boolean[][] visited = new boolean[m][n];
308+
309+
// 定义一个HashMap,记录某片岛屿的标记号和面积
310+
HashMap<Integer, Integer> getSize = new HashMap<>();
311+
312+
// 定义一个HashSet,用来判断某一位置水四周是否存在不同标记编号的岛屿
313+
HashSet<Integer> set = new HashSet<>();
314+
315+
// 定义一个boolean变量,看看DFS之后,是否全是岛屿
316+
boolean isAllIsland = true;
317+
318+
// 遍历二维数组进行DFS搜索,标记每片岛屿的编号,记录对应的面积
319+
for (int i = 0; i < m; i++) {
320+
for (int j = 0; j < n; j++) {
321+
if (grid[i][j] == 0) isAllIsland = false;
322+
if (grid[i][j] == 1) {
323+
count = 0;
324+
dfs(grid, i, j, visited);
325+
getSize.put(mark, count);
326+
mark++;
327+
}
328+
}
329+
}
330+
331+
int result = 0;
332+
if (isAllIsland) result = m * n;
333+
334+
// 对标记完的grid继续遍历,判断每个水位置四周是否有岛屿,并记录下四周不同相邻岛屿面积之和
335+
// 每次计算完一个水位置周围可能存在的岛屿面积之和,更新下result变量
336+
for (int i = 0; i < m; i++) {
337+
for (int j = 0; j < n; j++) {
338+
if (grid[i][j] == 0) {
339+
set.clear();
340+
// 当前水位置变更为岛屿,所以初始化为1
341+
int curSize = 1;
342+
343+
for (int[] dir : dirs) {
344+
int curRow = i + dir[0];
345+
int curCol = j + dir[1];
346+
347+
if (curRow < 0 || curRow >= m || curCol < 0 || curCol >= n) continue;
348+
int curMark = grid[curRow][curCol];
349+
// 如果当前相邻的岛屿已经遍历过或者HashMap中不存在这个编号,继续搜索
350+
if (set.contains(curMark) || !getSize.containsKey(curMark)) continue;
351+
set.add(curMark);
352+
curSize += getSize.get(curMark);
353+
}
354+
355+
result = Math.max(result, curSize);
356+
}
357+
}
358+
}
359+
360+
// 打印结果
361+
System.out.println(result);
362+
}
363+
}
364+
365+
```
261366

262367
### Python
263368

problems/kamacoder/0110.字符串接龙.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,68 @@ int main() {
153153
## 其他语言版本
154154

155155
### Java
156+
```Java
157+
public class Main {
158+
// BFS方法
159+
public static int ladderLength(String beginWord, String endWord, List<String> wordList) {
160+
// 使用set作为查询容器,效率更高
161+
HashSet<String> set = new HashSet<>(wordList);
162+
163+
// 声明一个queue存储每次变更一个字符得到的且存在于容器中的新字符串
164+
Queue<String> queue = new LinkedList<>();
165+
166+
// 声明一个hashMap存储遍历到的字符串以及所走过的路径path
167+
HashMap<String, Integer> visitMap = new HashMap<>();
168+
queue.offer(beginWord);
169+
visitMap.put(beginWord, 1);
170+
171+
while (!queue.isEmpty()) {
172+
String curWord = queue.poll();
173+
int path = visitMap.get(curWord);
174+
175+
for (int i = 0; i < curWord.length(); i++) {
176+
char[] ch = curWord.toCharArray();
177+
// 每个位置尝试26个字母
178+
for (char k = 'a'; k <= 'z'; k++) {
179+
ch[i] = k;
180+
181+
String newWord = new String(ch);
182+
if (newWord.equals(endWord)) return path + 1;
183+
184+
// 如果这个新字符串存在于容器且之前未被访问到
185+
if (set.contains(newWord) && !visitMap.containsKey(newWord)) {
186+
visitMap.put(newWord, path + 1);
187+
queue.offer(newWord);
188+
}
189+
}
190+
}
191+
}
192+
193+
return 0;
194+
}
195+
196+
public static void main (String[] args) {
197+
/* code */
198+
// 接收输入
199+
Scanner sc = new Scanner(System.in);
200+
int N = sc.nextInt();
201+
sc.nextLine();
202+
String[] strs = sc.nextLine().split(" ");
203+
204+
List<String> wordList = new ArrayList<>();
205+
for (int i = 0; i < N; i++) {
206+
wordList.add(sc.nextLine());
207+
}
208+
209+
// wordList.add(strs[1]);
210+
211+
// 打印结果
212+
int result = ladderLength(strs[0], strs[1], wordList);
213+
System.out.println(result);
214+
}
215+
}
216+
217+
```
156218

157219
### Python
158220

0 commit comments

Comments
 (0)