转载请注明出处:

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. jquery模拟form表单提交并新打开页面

    /** * form表单提交本页面打开 * @param url * @param params */ function postCurrent(url,params){ var form = $(& ...

  2. INSERT 中ON DUPLICATE KEY UPDATE的使用

    如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE.例如,如果列a被定义为UNIQUE,并 ...

  3. hdu 2364 Escape【模拟优先队列】【bfs】

    题目链接:https://vjudge.net/contest/184966#problem/A 题目大意: 走迷宫.从某个方向进入某点,优先走左或是右.如果左右都走不通,再考虑向前.绝对不能往后走, ...

  4. Django 学习第八天——Django模型基础第三节

    一.表关系的实现: 一对一:OneToOne(外键+唯一键) xxx = models.OneToOneField('关联的表',on_delete=models.CASCADE) 外键和一对一关系的 ...

  5. Newtonsoft.Json日期转换

    在使用EasyUI做后台时,使用表格datagrid,用Newtonsoft.Json转换为Json格式后,时间显示为2013-06-15 T00:00:00形式. 后来研究了一下Newtonsoft ...

  6. Linux学习笔记 1 环境变量 2 vi命令

    1 环境变量篇 1.1  修改 查看 生效 系统环境变量 1 涉及系统环境变量的文件   -->  .bash_profile --> /etc/profile 2 该文件位置 /root ...

  7. 修改HAL标准库用printf函数发送数据直接输出

    主函数文件,请直接关注自己写上去的代码: 直接看43行代码:#include "stdio.h"//要添加这个头文件 还有97行到112行:实现用HAL库函数和printf函数发送 ...

  8. vue插槽,也就是子页面、父页面相互传值的另一写法

    父页面: <template> <div class="parent"> <p>父组件</p> <child> < ...

  9. vue中,class与style绑定

    <template> <div> <p v-bind:class="{active:isActive,'demo':Demo}">嘿嘿</ ...

  10. g++ 动态库的编译及使用

    #ifndef __HELLO_H_ #define __HELLO_H_ void print(); #endif #include "hello.h" #include < ...