目录
岛屿的最⼤⾯积(medium)
题目解析
讲解算法原理
编写代码
被围绕的区域(medium)
题目解析
讲解算法原理
编写代码
岛屿的最⼤⾯积(medium)
题目解析
1.题目链接:. - 力扣(LeetCode)
2.题目描述
给你⼀个⼤⼩为mxn的⼆进制矩阵grid。岛屿是由⼀些相邻的1(代表⼟地)构成的组合,这⾥的「相邻」要求两个1必须在⽔平或者竖直的
四个⽅向上相邻。你可以假设grid的四个边缘都被0(代表⽔)包围着。岛屿的⾯积是岛上值为1的单元格的数⽬。
计算并返回grid中最⼤的岛屿⾯积。如果没有岛屿,则返回⾯积为0。
⽰例1:
输⼊:
grid=[[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]]
输出:6解释:
答案不应该是11,因为岛屿只能包含⽔平或垂直这四个⽅向上的1。
⽰例2:输⼊:
grid=[[0,0,0,0,0,0,0,0]]
输出:0
提⽰:
m==grid.length
n==grid[i].length
1<=m,n<=50
grid[i][j]为0或1
讲解算法原理
算法思路:
• 遍历整个矩阵,每当遇到⼀块⼟地的时候,就⽤「深搜」或者「宽搜」将与这块⼟地相连的「整个岛屿」的⾯积计算出来。
• 然后在搜索得到的「所有的岛屿⾯积」求⼀个「最⼤值」即可。
• 在搜索过程中,为了「防⽌搜到重复的⼟地」:
◦ 可以开⼀个同等规模的「布尔数组」,标记⼀下这个位置是否已经被访问过;◦ 也可以将原始矩阵的 1 修改成 0 ,但是这样操作会修改原始矩阵。
4. 解法(深搜dfs):
算法流程:
• 主函数内:
a. 遍历整个数组,发现⼀块没有遍历到的⼟地之后,就⽤ dfs ,将与这块⼟地相连的岛屿的⾯
积求出来;
b. 然后将⾯积更新到最终结果 ret 中。
• 深搜函数 dfs 中:
a. 能够进到 dfs 函数中,说明是⼀个没遍历到的位置;
b. 标记⼀下已经遍历过,设置⼀个变量 S = 1 (当前这个位置的⾯积为 1 ),记录最终的⾯
积;
c. 上下左右遍历四个位置:
▪ 如果找到⼀块没有遍历到的⼟地,就将与这块⼟地相连的岛屿⾯积累加到 S 上;d. 循环结束后, S 中存的就是整块岛屿的⾯积,返回即可。
编写代码
c++算法代码:
class Solution
{bool vis[51][51];int m, n;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};int count;
public:int maxAreaOfIsland(vector<vector<int>>& grid) {m = grid.size(), n = grid[0].size();int ret = 0;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(!vis[i][j] && grid[i][j] == 1){count = 0;dfs(grid, i, j);ret = max(ret, count);}return ret;}void dfs(vector<vector<int>>& grid, int i, int j){count++;vis[i][j] = true;for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y]
== 1){dfs(grid, x, y);}}}
};
java算法代码:
class Solution
{boolean[][] vis;int m, n;int[] dx = {0, 0, -1, 1};int[] dy = {1, -1, 0, 0};int count;public int maxAreaOfIsland(int[][] grid) {m = grid.length; n = grid[0].length;vis = new boolean[m][n];int ret = 0;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){if(!vis[i][j] && grid[i][j] == 1){count = 0;dfs(grid, i, j);ret = Math.max(ret, count);}}return ret;}public void dfs(int[][] grid, int i, int j){count++;vis[i][j] = true;for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y]
== 1)dfs(grid, x, y);}}
}
被围绕的区域(medium)
题目解析
1.题目链接:. - 力扣(LeetCode)
2.题目描述
给你⼀个mxn的矩阵board,由若⼲字符'X'和'O',找到所有被'X'围绕的区域,并将这些区域⾥所有的'O'⽤'X'填充。
⽰例1:
输⼊:board=[["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的'O'都不会被填充为'X'。任何不在边界上,或不与边界上的'O'相连的'O'最终都会被填充为'X'。如果两个元素在⽔平或垂直⽅向相邻,则称它们是“相连”的。
⽰例2:输⼊:board=[["X"]]输出:[["X"]]
提⽰:
m==board.length
n==board[i].length
1<=m,n<=200
board[i][j]为'X'或'O'
讲解算法原理
解法:
算法思路:
正难则反。
可以先利⽤ dfs 将与边缘相连的 '0' 区域做上标记,然后重新遍历矩阵,将没有标记过的 '0' 修改成 'X' 即可。
编写代码
c++算法代码:
class Solution
{int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m, n;
public:void solve(vector<vector<char>>& board) {m = board.size(), n = board[0].size();// 1. 把边界的 O 相连的联通块,全部修改成 .for(int j = 0; j < n; j++){if(board[0][j] == 'O') dfs(board, 0, j);if(board[m - 1][j] == 'O') dfs(board, m - 1, j);}for(int i = 0; i < m; i++){if(board[i][0] == 'O') dfs(board, i, 0);if(board[i][n - 1] == 'O') dfs(board, i, n - 1);}// 2. 还原for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){if(board[i][j] == '.') board[i][j] = 'O';else if(board[i][j] == 'O') board[i][j] = 'X';}}void dfs(vector<vector<char>>& board, int i, int j){board[i][j] = '.';for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O'){dfs(board, x, y);}}}
};
java算法代码:
class Solution
{int m, n;int[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};public void solve(char[][] board) {m = board.length; n = board[0].length;// 1. 先把边界的 O 相连的联通块,全部修改成 '.'for(int j = 0; j < n; j++){if(board[0][j] == 'O') dfs(board, 0, j);if(board[m - 1][j] == 'O') dfs(board, m - 1, j);}for(int i = 0; i < m; i++){if(board[i][0] == 'O') dfs(board, i, 0);if(board[i][n - 1] == 'O') dfs(board, i, n - 1);}// 2. 还原for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){if(board[i][j] == '.') board[i][j] = 'O';else if(board[i][j] == 'O') board[i][j] = 'X';}}public void dfs(char[][] board, int i, int j){board[i][j] = '.';for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O'){dfs(board, x, y);}}}
}