【算法分析与设计】【第七周】200 & 695. Number(Max Area) of Islands
来源:互联网 发布:mac php开发环境 编辑:程序博客网 时间:2024/06/06 11:41
题目来源:200:https://leetcode.com/problems/number-of-islands/description/
695:https://leetcode.com/problems/max-area-of-island/description/
BFS\DFS巩固。关联旧题。小题升级。
- Number of Islands
- 题目大意
- 思路
- 代码
- 关联的旧题
- 遇到的问题
- 200升级版695 Max Area of Island
- 题目大意
- 思路
- 代码
- 遇到的问题
200. Number of Islands
题目大意
在字符“0”和“1”组成的矩阵中,“0”代表海水,“1”代表岛屿,连在一起的小岛屿组成一个大岛(对角线不算连在一起)。
找出大岛的总个数。
例
11000
11000
00100
00011
Answer: 3
思路
- 利用一个visited二维数组来标志一个数是否被访问过。
- 利用广度优先搜索来找连在一起的小岛屿所组成的一个大岛。
- 统计广度优先搜索的次数,即大岛的总个数。
代码
#define NMAX 1000 int visited[NMAX][NMAX] = {0}; void bfs(char** grid, int gridRowSize, int gridColSize, int i, int j) { if (i >= 0 && i < gridRowSize && j >= 0 && j < gridColSize && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j - 1); bfs(grid, gridRowSize, gridColSize, i, j + 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); }} int numIslands(char** grid, int gridRowSize, int gridColSize) { for (int i = 0; i < NMAX; i++) for (int j = 0; j < NMAX; j++) visited[i][j] = 0; int count = 0; for (int i = 0; i < gridRowSize; i++) { for (int j = 0; j < gridColSize; j++) { if (visited[i][j] == 0 && grid[i][j] == '1') { count++; bfs(grid, gridRowSize, gridColSize, i, j); } } } return count;}
关联的旧题
200这题可以说是博客第四周记录的题目547. Friend Circles的升级版。
547也是一道与图有关的题目,可简化成找出无向图中连通图的个数。
相较之下,200与典型的图不太相同,不能简单地说有向无向,毕竟行列数都不一致。为了解决行列数不一致的问题,我们只好把visited数组从一维数组改为二维数组,用于记录grid中的每个点。难度有所提升。
遇到的问题
处理下标的时候,想到grid的边界和中间应该采用不同的递归式。比如grid[0][0]就只用找grid[0][1]、grid[1][0],并不用上下左右都找一边,找了也是越界。于是写了一下几个边界处理:
if (i > 0 && i < gridRowSize-1 && j > 0 && j < gridColSize-1 && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j - 1); bfs(grid, gridRowSize, gridColSize, i, j + 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); } else if (i == 0 && j > 0 && j < gridColSize-1 && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i, j - 1); bfs(grid, gridRowSize, gridColSize, i, j + 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); } else if (i > 0 && i < gridRowSize-1 && j == 0 && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j + 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); } else if (i == 0 && j == 0 && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i, j + 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); } else if (i == gridRowSize-1 && j > 0 && j < gridColSize-1 && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j - 1); bfs(grid, gridRowSize, gridColSize, i, j + 1); } else if (i > 0 && i < gridRowSize-1 && j == gridColSize-1 && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j - 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); } else if (i == gridRowSize-1 && j == gridColSize-1 && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j - 1); }
但是关心则乱,一通处理下来,反而使算法的逻辑不清楚了。运行了一下,错误bug一堆。但是这么一大坨代码,自己根本都不想看。
后来静下来捋一捋,发现越界的行列参数i、j根本传不进if语句,一大坨可以直接简化成:
if (i >= 0 && i < gridRowSize && j >= 0 && j < gridColSize && !visited[i][j] && grid[i][j] == '1') { visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j - 1); bfs(grid, gridRowSize, gridColSize, i, j + 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); }
嗯,舒服多了。
~ o( ̄▽ ̄)o~
(200升级版)695. Max Area of Island
题目大意
在0和1组成的矩阵中,0代表海水,1代表岛屿,连在一起的小岛屿组成一个大岛(对角线不算连在一起)。
找出所有大岛中最大的岛,并输出组成该大岛的小岛屿的个数。
例
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
Given the above grid, return 6.
思路
这题其实和200是一模一样的,只不过多了一步“输出组成该大岛的小岛屿的个数”。这很容易解决,只要加一个计数器,在每次扫描点的时候把该连通区域内扫过的点的个数累加便可。
代码
为了方便,这里的计数器用全局变量。
#include <stdio.h>#include <stdlib.h>#define NMAX 51int visited[NMAX][NMAX] = {0}; int count = 0;void bfs(int** grid, int gridRowSize, int gridColSize, int i, int j) { if (i >= 0 && i < gridRowSize && j >= 0 && j < gridColSize && !visited[i][j] && grid[i][j] == 1) { count++; visited[i][j] = 1; bfs(grid, gridRowSize, gridColSize, i - 1, j); bfs(grid, gridRowSize, gridColSize, i, j - 1); bfs(grid, gridRowSize, gridColSize, i, j + 1); bfs(grid, gridRowSize, gridColSize, i + 1, j); }} int maxAreaOfIsland(int** grid, int gridRowSize, int gridColSize) { for (int i = 0; i < NMAX; i++) for (int j = 0; j < NMAX; j++) visited[i][j] = 0; int max = 0; for (int i = 0; i < gridRowSize; i++) { for (int j = 0; j < gridColSize; j++) { count = 0; if (visited[i][j] == 0 && grid[i][j] == 1) { bfs(grid, gridRowSize, gridColSize, i, j); if (count > max) max = count; } } } return max;}
遇到的问题
没啥大问题
- 不要把max和count混淆。
- 每一次做bfs前要把count清零。
- 【算法分析与设计】【第七周】200 & 695. Number(Max Area) of Islands
- 200 Number of Islands
- 200Number of Islands
- 200 Number of Islands
- [leetcode-200]Number of Islands(java)
- LeetCode(200) Number of Islands
- LeetCode 200 Number of Islands(DFS)
- 200 Number of Islands(岛屿数量)
- Number of Islands (第三周 DFS)
- 算法分析与设计第七周
- [LeetCode 200]Number of Islands
- leetcode 200 : Number of Islands
- LeetCode #200 Number of Islands
- LeetCode(200)Number of Islands
- leetcode 200: Number of Islands
- [LeetCode 200] Number of Islands
- Leetcode #200 Number of Islands
- LeetCode 200 Number of Islands
- Collection集合
- 微信小程序框架wxml(二)wxml列表渲染
- SPOJ-1811 Longest Common Substring(后缀自动机)
- C语言函数的递归和调用实例分析
- 添加Context元素的目的是使得Tomcat能够把web应用识别出来
- 【算法分析与设计】【第七周】200 & 695. Number(Max Area) of Islands
- 对js函数作用域的进一步理解
- html中contentEditable属性
- 磁盘与文件系统管理--鸟哥私房菜读书笔记
- 函数的相关知识
- -bash: /usr/bin/yum: /usr/bin/python2.6.62.6.6: bad interpreter: No such file or directory
- linux后台查看共享内存和消息队列的命令
- 【常见排序算法】以最简单的方式理解归并排序
- 计算机视觉中的学习资料