岛屿最大面积 leetcode Java_LeetCode刷题记录——岛屿的最大面积

题目描述:

给定一个包含了一些 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.com2eea35ff8e0f380887688449344b1995.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值