(原)Max Area of Island(即连通域标记)
转载请注明出处:
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(即连通域标记)的更多相关文章
- 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 用了第一种方式, ...
- Leetcode之深度优先搜索(DFS)专题-695. 岛屿的最大面积(Max Area of Island)
Leetcode之深度优先搜索(DFS)专题-695. 岛屿的最大面积(Max Area of Island) 深度优先搜索的解题详细介绍,点击 给定一个包含了一些 0 和 1的非空二维数组 grid ...
- C#LeetCode刷题之#695-岛屿的最大面积( Max Area of Island)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3736 访问. 给定一个包含了一些 0 和 1的非空二维数组 gr ...
- [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 ...
- 【leetcode】Max Area of Island
国庆中秋长假过完,又要开始上班啦.先刷个题目找找工作状态. Given a non-empty 2D array grid of 0's and 1's, an island is a group o ...
- [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 ...
- 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 ...
- 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 ...
- [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 ...
随机推荐
- 2018WFU校赛B题
我们在ACM的题目中已经了解了什么是ACM了,ACM还是很残酷的了(ಥ _ ಥ),那么现在你就要解决一个ACM最简单的题了,简单到省赛和区域赛都不会出这种简单的题.ls很强,即使每年都在ACM这个大坑 ...
- JAVA程序的基本结构
java程序(类)其实是一个静态方法库,或者是定义了一个数据类型.所以会遵循7种语法: 1.原始数据类型: ---整型:byte.short.int.long ---浮 ...
- 治愈 JavaScript 疲态的学习计划【转载】
来源:伯乐在线 - Rose Wang 像其他人一样,最近我读了 Jose Aguinaga 的文章 <How it feels to learn JavaScript in 2016>. ...
- [Python] Marshmallow QuickStart
常用小操作索引 指定fields必须:fields.String(required=True) 部分loading: 不load name:result = UserSchema.load({'ema ...
- python基础一 ------如何统计一个列表元素的频度
如何统计一个列表元素的频度 两个需求: 1,统计一个随机序列[1,2,3,4,5,6...]中的出现次数前三的元素及其次数 2,统计一片英文文章中出现次数前10 的单词 两种方法: 1,普通的for循 ...
- Spring MVC中Controller返回值void时报错
Controller如下: 当使用url访问该处理器方法时,报错如下: 26-Jan-2019 21:16:28.105 警告 [http-nio-8080-exec-39] org.springfr ...
- CDQ分治入门 + 例题 Arnooks's Defensive Line [Uva live 5871]
CDQ分治入门 简介 CDQ分治是一种特别的分治方法,它由CDQ(陈丹琦)神犇于09国家集训队作业中首次提出,因此得名.CDQ分治属于分治的一种.它一般只能处理非强制在线的问题,除此之外这个算法作为某 ...
- [jzoj]3777.最短路(shortest)
Link https://jzoj.net/senior/#main/show/3777 Description 小Y最近学得了最短路算法,一直想找个机会好好练习一下.话虽这么说,OJ上最短路的题目都 ...
- Yii2 组件
组件的命名空间: 响应组件: yii\web\Response Yii预定义的HTTP异常组件: yii\web\BadRequestHttpException: //状态码 400. yii\web ...
- Java 基础 集合框架
Java中的集合从类的继承和接口的实现结构来说,可以分为两大类: 1 继承自Collection接口,包含List.Set和Queue等接口和实现类. 2 继承自Map接口,主要包含哈希表相关的集合类 ...