首页 > 其他分享 >二维矩阵中1所构成的块个数(孤岛问题)

二维矩阵中1所构成的块个数(孤岛问题)

时间:2022-11-08 22:02:00浏览次数:59  
标签:count int 矩阵 DFS 二维 孤岛 col row


二维矩阵中1所构成的块个数(孤岛问题),进行了总结。转载请注明链接,有问题请及时联系博主:​​Alliswell_WP​​

》问题描述:给定一个n*n的矩阵里面是0或1算出里面独立的0群组的数量。比如
0 0 1 1 1
0 1 1 1 0
1 1 1 1 0
1 0 1 1 1
1 1 1 1 1

答案:3。

》思路:虽然不是图,但是仍然可以用图的DFS思想。更没有必要用实现它对应的图。为了计数同时为了节省空间,把矩阵的元素本身来作为DFS时使用的标记量visited[ ]。

(1)采用深度优先搜索,遍历1在数组中的位置,对于遍历得到的1,先将其置位0再递归遍历该位置周围8个方向上是否为1,如果为1将其值变为0。这样顺次得到的1的个数就为最终结果;
(2)标注法:用count变量标注块的编号。从左到右从上到下遍历数组,对于值为1的位置,如果其左上,上,右上,左都为0,那么该位置的值变为count+1;否则该位置的值变为其左上,上,右上,左位置的值。最后根据count就可以求得块的个数。
(3)通过并查集解决;
上面方法的时间复杂度都为O(n)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <malloc.h>
const int row = 5, col = 5;
//图的DFS,把所有连通结点标记为count
void DFS(int m[][col], int i, int j, int row, int col, int count)
{
m[i][j] = count;
if (i>0 && m[i - 1][j] == 0)
{
DFS(m, i - 1, j, row, col, count);
}
if (j>0 && m[i][j - 1] == 0)
{
DFS(m, i, j - 1, row, col, count);
}
if (i<row - 1 && m[i + 1][j] == 0)
{
DFS(m, i + 1, j, row, col, count);
}
if (j<col - 1 && m[i][j + 1] == 0)
{
DFS(m, i, j + 1, row, col, count);
}
}

//对每个"为0且没有被标记"的结点进行DFS
int get_group(int m[][col], int row, int col)
{
int count = 1; //01都被占用了,所以从2起始吧
for (int i = 0; i<row; i++)
{
for (int j = 0; j<col; j++)
{
if (m[i][j] == 0)
{
count++;
DFS(m, i, j, row, col, count);
}
}
}
return count - 1;//我是从2起始的
}

void display(int m[][5])
{
for (int i = 0; i<row; i++)
{
for (int j = 0; j<col; j++)
printf("%d ", m[i][j]);
printf("\n");
}

}
int main()
{
#if 0
//手工输入矩阵的方式

int(*m)[col] = (int(*)[col])malloc(sizeof(int)*row*col);
for (int i = 0; i<row; i++)
for (int j = 0; j<col; j++)
scanf("%d", &m[i][j]);
#endif

#if 1
//二维数组初始化的方式
int m[][col] = { { 0,0,1,1,1 },
{ 0,1,1,1,0 },
{ 1,1,0,1,0 },
{ 1,0,1,0,0 },
{ 1,0,0,0,1 } };
#endif

display(m);
printf("%d\n", get_group(m, row, col));
display(m);
system("pause");
return 0;
}


》代码优化:改为手动输入二维矩阵的行数、列数和二维矩阵中0/1元素。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <malloc.h>
#include<iostream>

using namespace std;
//const int row = 5, col = 5;
static int row , col;
//图的DFS,把所有连通结点标记为count
void DFS(int **m, int i, int j, int row, int col, int count)
{
m[i][j] = count;
if (i>0 && m[i - 1][j] == 0)
{
DFS(m, i - 1, j, row, col, count);
}
if (j>0 && m[i][j - 1] == 0)
{
DFS(m, i, j - 1, row, col, count);
}
if (i<row - 1 && m[i + 1][j] == 0)
{
DFS(m, i + 1, j, row, col, count);
}
if (j<col - 1 && m[i][j + 1] == 0)
{
DFS(m, i, j + 1, row, col, count);
}
}

//对每个"为0且没有被标记"的结点进行DFS
int get_group(int **m, int row, int col)
{
int count = 1; //01都被占用了,所以从2起始吧
for (int i = 0; i<row; i++)
{
for (int j = 0; j<col; j++)
{
if (m[i][j] == 0)
{
count++;
DFS(m, i, j, row, col, count);
}
}
}
return count - 1;//我是从2起始的
}

void display(int **m, int row, int col)
{
for (int i = 0; i<row; i++)
{
for (int j = 0; j<col; j++)
printf("%d ", m[i][j]);
printf("\n");
}

}
int main()
{
#if 1
//手工输入矩阵的方式
cin >> row >> col;
int **m;
m = new int*[row]; //注意,int*[10]表示一个有10个元素的指针数组
for (int i = 0; i < row; ++i)
{
m[i] = new int[col];
}

//int(*m)[col] = (int(*)[col])malloc(sizeof(int)*row*col);
for (int i = 0; i<row; i++)
for (int j = 0; j<col; j++)
scanf("%d", &m[i][j]);
#endif

#if 0
//二维数组初始化的方式
int m[][col] = { { 0,0,1,1,1 },
{ 0,1,1,1,0 },
{ 1,1,0,1,0 },
{ 1,0,1,0,0 },
{ 1,0,0,0,1 } };
#endif

display(m,row, col);
printf("%d\n", get_group(m, row, col));
display(m, row, col);
for (int i = 0; i < col; i++)
{
delete[] m[i];
}
delete[] m;
system("pause");
return 0;
}

二维矩阵中1所构成的块个数(孤岛问题),进行了总结。转载请注明链接,有问题请及时联系博主:Alliswell_WP

题目:给定一个n*n的矩阵里面是0或1算出里面独立的0群组的数量。比如
0 0 1 1 1
0 1 1 1 0
1 1 1 1 0
1 0 1 1 1
1 1 1 1 1

答案:3。


思路:虽然不是图,但是仍然可以用图的DFS思想。更没有必要用实现它对应的图。为了计数同时为了节省空间,把矩阵的元素本身来作为DFS时使用的标记量visited[ ]。

标签:count,int,矩阵,DFS,二维,孤岛,col,row
From: https://blog.51cto.com/u_15405812/5834972

相关文章

  • 点云_矩阵旋转后平移和平移后旋转_open3d读写PCD
    矩阵运算变换矩阵是先旋转再平移P=R*p+t1先平移再旋转的话P=R(p+t2)=R*p+R*t2其中平移矩阵之间的关系是t1=R*t2示例代码#-*-coding:ut......
  • 59. 螺旋矩阵 II
    59.螺旋矩阵II给你一个正整数 n,生成一个包含1到 n2 所有元素,且元素按顺时针顺序螺旋排列的 nxn正方形矩阵matrix。 示例1:输入:n=3输出:[[1,2,3],......
  • Power Board (CF2,E) (bitset二维+找规律)
     思路:把数据列出来,因为是腻的关系,发现就和指数有关然后这个就是要去掉重复的,有重复的数又是和他的ni有关系,发现数据范围可以用bitset,时间空间都行,于是就......
  • C++ 不知图系列之基于邻接矩阵实现广度、深度搜索
    1.前言图是一种抽象数据结构,本质和树结构是一样的。图与树相比较,图具有封闭性,可以把树结构看成是图结构的基础部件。在树结构中,如果把兄弟节点之间或子节点之间横向连接,......
  • 二维数组的前缀和
    二维数组的前缀和设二维数组,intarr[5][7];,以arr[1][1]作为作为矩形的左上角坐标,以此开始存储数据,数组最左边,最上边不存储数据,为空设二维数组,int......
  • leetcode 54. 螺旋矩阵 js高效实现
    给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。示例1:  输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]......
  • 矩阵论考点分析(中国抗业带学-铜专分校)
    第1章线性空间与线性映射求解过渡矩阵(表示矩阵)并进行坐标变换;空间Vn(F):ξ=[ξ1⋯ξn]和η=[η1⋯ηn]是基,T是线性变换,α∈Vn(F)任意。已知α在ξ下的坐标为x=[x......
  • 【模板】二维数点
    postedon2022-10-2313:50:24|under模板|sourceproblem给定一个二维平面,多次询问\(x\in[l_x,r_x],y\in[l_y,r_y]\)的点有多少个。solution1(静态+在线):可持久化......
  • 求3*3矩阵对角线元素之和
    #include<stdio.h>intmain(){ inta[3][3]={{1,2,3},{4,5,6},{7,8,9}}; inti; intsum=0; for(i=0;i<3;i++){ sum+=a[i][i]; } printf("su......
  • C语言初级阶段4——数组2————二维数组
    C语言初级阶段4——数组2————二维数组二维数组的定义:类型说明符数组名[数组大小][数组大小]第一个大小是行的大小,第二个大小是列的大小。二维数组的初始化:{}#in......