转载请注明出处:

https://www.cnblogs.com/darkknightzh/p/10493114.html

1. 问题

Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.

Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.)

Example 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. Note the answer is not 11, because the island must be connected 4-directionally. Example 2: [[0,0,0,0,0,0,0,0]]
Given the above grid, return 0.

2 解决方法

这题就是连通域标记,用matlab的[~,num]=bwlabel(data,4)直接可以得到对于example 1,num=6。

纯粹编程的话,有想到了两种方法:

1 深度优先遍历,对于某个为1的点,遍历其周围的4个点,直到到达边界或者为0。

2 得到值为1的坐标,然后计算|x1-y1|+|x2-y2|=1的坐标,并把这些坐标连起来,就是一个区域了,比如点a连接点b,点b连接点d,点d连接点c,则a,b,c,d这四个点是连起来的一个区域,串起来即可。

对于第一种方法,写起来简单一些。对于第二种方法,不清楚有没有简单的写法,本文只能使用最笨的方法,验证了两个example都是正确的,没有进一步验证其他数据。

3 Matlab代码

Matlab代码如下(使用深度优先遍历):

function testIsland()

clc
clear all
close all % data = [[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]]; data = [[0,0,0,0,0,0,0,0]]; [island_num, ~] = island(data); end function [island_num, label] = island(data)
island_num = 0;
label = data;
for i=1:size(label, 1)
for j=1:size(label, 2)
if label(i, j)==1
island_num = island_num +1;
label = recurseFinding(label, i, j, island_num);
end
end
end
end function data = recurseFinding(data, i, j, island_num)
if i>0 && i<=size(data, 1) && j>0 && j<=size(data, 2) && data(i, j)==1
data(i, j) = island_num;
data = recurseFinding(data, i-1, j, island_num);
data = recurseFinding(data, i+1, j, island_num);
data = recurseFinding(data, i, j-1, island_num);
data = recurseFinding(data, i, j+1, island_num);
end
end

4. python代码

Python代码使用第二种方法,将连接的点串起来(不知道有没有好的解决方法,下面的代码比较笨,另外,代码中method1和method2都可以,method1计算量大一些,method2计算量小一些,但是不确定method2是不是完全正确。。。)

 import numpy as np
import copy def recurseFinding(dict_in, key, islands):
ret_list = []
for val in dict_in[key]:
ret_list.append(val)
if dict_in.__contains__(val) and not islands.__contains__(val):
ret_list = list(set(ret_list + [l for l in recurseFinding(dict_in, val, islands)]))
return ret_list def island_num(data):
loc_xy = [[i, j] for i in range(data.shape[0]) for j in range(data.shape[1]) if data[i,j]>0] # 得到不为0的所有坐标(x,y)
loc_idx_dict = {i:loc_xy[i] for i in range(len(loc_xy))} # 给坐标编号,方便后面使用
loc_key = sorted(set(loc_idx_dict.keys())) pairs_dict = {}
for i in range(len(loc_key)-1):
for j in range(i+1, len(loc_key)):
if abs(loc_idx_dict[loc_key[i]][0] - loc_idx_dict[loc_key[j]][0]) + abs(loc_idx_dict[loc_key[i]][1] - loc_idx_dict[loc_key[j]][1]) == 1:
if not pairs_dict.__contains__(loc_key[i]):
pairs_dict[loc_key[i]] = []
pairs_dict[loc_key[i]].append(loc_key[j]) islands_dict = {}
for k, v in pairs_dict.items():
if k in [j for i in islands_dict.values() for j in i]:
continue
if not islands_dict.__contains__(k):
islands_dict[k] = copy.deepcopy(pairs_dict[k])
islands_dict[k] = recurseFinding(pairs_dict, k, islands_dict) ############### method1
# islands_keys = sorted(set(islands_dict.keys())) # 可能出现11:[18,19], 12:[18]的情况,需要将12合并到11中,继续遍历一下,此处比较麻烦
# for i in range(len(islands_keys)-1):
# for j in range(i+1, len(islands_keys)):
# flags= False
# for v2 in islands_dict[islands_keys[j]]:
# if v2 in islands_dict[islands_keys[i]]:
# islands_dict[islands_keys[i]].append(islands_keys[j])
# flags = True
# if flags:
# islands_dict[islands_keys[j]] = [] # 此处无法删除12的key,否则程序崩溃,因而只能置空,后面删除 ############### method1 end ############### method2
reverse_pairs = {} # 得到反转的对应关系,如果出现11:[18,19], 12:[18]的情况,则反转后的键18对应2个值
for k,v in islands_dict.items():
for v0 in v:
if not reverse_pairs.__contains__(v0):
reverse_pairs[v0] = []
reverse_pairs[v0].append(k) delete_key = [] # 理论上比method1计算量少,但是不确定是否完全正确。。。
for k,v in reverse_pairs.items():
if len(v) > 1:
for i in range(1, len(v)):
if v[i] not in islands_dict[v[0]]:
islands_dict[v[0]].append(v[i])
if v[i] not in delete_key:
delete_key.append(v[i]) for k in delete_key: # 删除对应的key
del islands_dict[k]
############### method2 end islands_dict = {k:set(v) for k, v in islands_dict.items() if len(v) > 0} pairs_keys = set(pairs_dict.keys())
pairs_vals = set([v0 for v in pairs_dict.values() for v0 in v])
alone_loc = set(loc_key) - (pairs_keys | pairs_vals) #由于优先级,后面需要加括号
islands_dict.update({i:[] for i in alone_loc}) # 将单独的位置合并到islands_dict中 return len(islands_dict) # 通过islands_dict及loc_idx_dict可以找到对应的坐标,此处省略 # data=np.array([ [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]]) data=np.array([[0,0,0,0,0,0,0,0]]) num = island_num(data)
print(num)

(原)Max Area of Island(即连通域标记)的更多相关文章

  1. leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions

    两种方式处理已经访问过的节点:一种是用visited存储已经访问过的1:另一种是通过改变原始数值的值,比如将1改成-1,这样小于等于0的都会停止. Number of Islands 用了第一种方式, ...

  2. Leetcode之深度优先搜索(DFS)专题-695. 岛屿的最大面积(Max Area of Island)

    Leetcode之深度优先搜索(DFS)专题-695. 岛屿的最大面积(Max Area of Island) 深度优先搜索的解题详细介绍,点击 给定一个包含了一些 0 和 1的非空二维数组 grid ...

  3. C#LeetCode刷题之#695-岛屿的最大面积( Max Area of Island)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3736 访问. 给定一个包含了一些 0 和 1的非空二维数组 gr ...

  4. [leetcode]python 695. Max Area of Island

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  5. 【leetcode】Max Area of Island

    国庆中秋长假过完,又要开始上班啦.先刷个题目找找工作状态. Given a non-empty 2D array grid of 0's and 1's, an island is a group o ...

  6. [LeetCode] Max Area of Island 岛的最大面积

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  7. 695. Max Area of Island最大岛屿面积

    [抄题]: 求最多的联通的1的数量 Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (repre ...

  8. LeetCode 695. Max Area of Island (岛的最大区域)

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  9. [Swift]LeetCode695. 岛屿的最大面积 | Max Area of Island

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

随机推荐

  1. Python 获取计算机全名(fully qualified host name)

    Python 获取计算机全名(fully qualified host name) import socket socket.getfqdn() socket.gethostname()

  2. Python “No module named” 以及在Python2中可以导入,但在python3中却出现的原因

    Python “No module named” 以及在Python2中可以导入,但在python3中却出现的原因 原因之1: 例如有这样的一个包和它的模块: Test __init__.py Mod ...

  3. P2279 [HNOI2003]消防局的设立

    P2279 [HNOI2003]消防局的设立考场上想出了贪心策略,但是处理细节时有点问题,gg了.从(当前深度最大的节点)叶子节点往上跳k个,在这里设消防局,并从消防局遍历k个距离,标记上. #inc ...

  4. dns服务扩展

  5. Django之ORM字段和字段参数

    ORM介绍 ORM概念 ORM由来 ORM的优势 ORM的劣势 ORM总结 Django中的ORM Django项目使用MySQL数据库 Model 快速入门 字段 自定义字段 字段参数 Model ...

  6. excel 删除重复项

    excel 删除重复项 单击“数据”按钮会出现如图所示,这时我们可以看到,在下分的菜单栏里有一个“删除重复项”选项,单击该选项.

  7. Axis2部署后服务器端出现异常信息

    客户端可以正常调用Web Service,但服务端控制台报出如下异常:2013-09-05 09:49:12,965:[http-8080-2] at org.apache.axis2.dataret ...

  8. Python3画图系列——NetworkX初探

    NetworkX 概述 NetworkX 主要用于创造.操作复杂网络,以及学习复杂网络的结构.动力学及其功能.用于分析网络结构,建立网络模型,设计新的网络算法,绘制网络等等.安装networkx看以参 ...

  9. 上海交大ACM总教头俞勇讲述“最聪明人的故事”

    这是一场世界大学生之间"最强大脑"的较量:这是拥有数十年历史的ACM国际大学生计算机程序设计大赛的赛场:斯坦福.加州理工.麻省理工.哈佛--当一个又一个在计算机科学领域拥有世界顶尖 ...

  10. json获取数据生成动态菜单(转)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...