(原)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 ...
随机推荐
- maven聚合工程无法install
对于maven聚合工程,有时候执行maven命令进行mvn clean install时会出一些莫名奇妙的错误: 一直报告找不到符号,仔细看了项目源代码也不知道是什么原因.首先确保项目所在路径为英文路 ...
- 用面向对象重写thread 实现多次调用一个线程
思路: 利用thread类中,run方法在子线程中调用,其他方法在主线程调用,所以将生产者写入主线程,将消费者写入run函数中在子线程中执行,完成生产者消费者模型 注意: 1. 要在 init 函数中 ...
- SORT--不要仅限于题目中
输入n,m 表示输入n个数输出前m个最大的数 Input The input file contains many test cases. Each case has 2 lines. The fir ...
- Activity插件化解决方案
--摘自<android插件化开发指南> 1.宿主App加载插件中的类 2.最简单的插件化方案就是在宿主的androidmanifest.xml中申明插件中的四大组件 把插件dex合并到宿 ...
- 【python】函数式编程
No1: 函数式编程:即函数可以作为参数传递,也可以作为返回值 No2: map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的 ...
- netty简单NIO模型
首先是使用java原生nio类库编写的例子,开发一套nio框架不简单,所以选择了netty,该例完成后,是netty举例. package com.smkj.netty; public class T ...
- [译]the cost of javascript in 2018(1)
前言 为了构建交互性网站,我们需要发送js给我们的用户,但很多情况下,我们使用了太多js. 在移动端,经常看到只加载了个点击链接或者滚动不了的情况. 实话说,js仍然是移动端最昂贵的资源,因为其在很大 ...
- 治愈 JavaScript 疲态的学习计划【转载】
来源:伯乐在线 - Rose Wang 像其他人一样,最近我读了 Jose Aguinaga 的文章 <How it feels to learn JavaScript in 2016>. ...
- [OC] Delegate的使用
建立两个页面 A 和 B,我们假设他们的文件名为ControllerA,ControllerB 由A页面,点击跳转到B页面.在B页面中,进行一些操作,并得到一个值,并将这个值传回给A页面,并在A页面上 ...
- 英语口语练习系列-C29-鸟类-辨别身份-断弦的琴
鸟类 sparrow sparrow 英 ['spærəʊ] 美 ['spæro] n. 麻雀:矮小的人 swallow swallow 英 ['swɒləʊ] 美 ['swɑlo] vt. 忍受:吞 ...