题目描述:
给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)
示例:
[[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
[[0,0,0,0,0,0,0,0]]
结果 => 0
题目难度:中等
心得体会:
这道题仔细分析一下能得出是实际是求一个无向图。因为限制了上下左右四个方向,当我们遍历到1的时候,我们便开始从四个方向去搜索。如果某个方向是1,则继续往上下左右去搜索。
比如,i = 0, j = 7的时候,值为1,我们需要遍历左右下,下方为0,于是将 i=1, j=7的值进行上下左右的遍历。我们使用递归的方式,通过改变节点的位置来遍历整个联通的线段。
大思路看起来没问题,使用一个深度优先遍历(DFS)就行。这里我思考几个问题。一是会不会死循环,比如上方进入下方,下方遍历又回到上方。第二个是已经遍历过的节点,在外部的二重循环到的时候,需不需要直接跳过。如果单次遍历的时候一个节点被不同的节点遍历,怎么计算?记录怎么保存?
一开始我使用从某个方向进入的节点不会返回改方向进行遍历。遍历过的数据用字符串保存在记录数组,然后每次查找一下是否在数组中。但是数据量大的时候会缺少某些节点,又很难调试。如果每次二重循环的时候重置记录数组,则会有许多重复遍历,超时。
后来参考了一下他人写的代码,改善了一下。
我们使用一个二维数组visited来保存该节点是否访问过。如果该节点为1,则visited[i][j] = 1。(依稀记得上数据结构课的时候学过,全还给老师了)
由于访问过的节点直接返回就可以了。我们不用担心递归无法结束的问题。最外层也不用重置。我们基于这样一个推测:如果一次遍历过的节点是另一次的遍历的开始,那么另一次的遍历结果就是那一次的结果,结点是联通的。
使用二维数组保存记录数组比数组["10","23"]这样的快很多,不用重置也大大提高了效率。
代码:
var maxAreaOfIsland = function(grid) {
var maxLength = 0;
var visited = [];
function hasSearched(pi, pj){
return visited[pi][pj] === 1
}
function findNeighbor(pi, pj) {
var islandLength = 0;
if(grid[pi][pj] === 1){
islandLength = 1;
//判断是否遍历过该节点 if(hasSearched(pi, pj)){
return 0;
}else{
visited[pi][pj] = 1;
}
//如果没有则继续遍历四个方向 if(pi > 0){
islandLength += findNeighbor(pi - 1, pj);
}
if(pi < grid.length - 1){
islandLength += findNeighbor(pi + 1, pj);
}
if(pj > 0){
islandLength += findNeighbor(pi, pj - 1);
}
if(pj < grid[pi].length -1){
islandLength += findNeighbor(pi, pj + 1);
}
}
return islandLength;
}
//初始化记录数组 for(var i = 0; i < grid.length; i++){
visited[i] = [];
for(var j = 0; j < grid[i].length; j++){
visited[i][j] = 0
}
}
for(var i = 0; i < grid.length; i++){
for(var j = 0; j < grid[i].length; j++){
//遍历每个节点 var islandLength = findNeighbor(i, j);
if(islandLength > maxLength){
maxLength = islandLength
}
}
}
return maxLength;
};
时间复杂度:好吧递归的我至今不会计算......希望大神能指点一二
题目链接:Loading...leetcode-cn.com