找出由‘1’组成的孤岛 & 找出孤岛的boundingBox

本文介绍了一种计算二维网格中岛屿数量的方法,并详细解释了两种不同的实现方式。此外,还提供了一个寻找由‘1’构成的连通区域边界框的算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

找出由‘1’组成的孤岛

面试题目,来自leetcode,曾经败在了这个简单的小题。。

Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
11000
00000

Answer: 1

Example 2:

11000
11000
00100
00011

Answer: 3

、、、、、、、、、、、、My accepted Answer 1、、、、、、、、、、、、、、

遍历整个数组,如果发现‘1’就将其及其临接的‘1’修改为0,就是这样。

int numIslands(char** grid, int gridRowSize, int gridColSize) {
    int Islands_Num = 0;
    for(int rowIdx = 0; rowIdx < gridRowSize; rowIdx++)
    {
        for(int columIdx = 0; columIdx < gridColSize; columIdx++)
        {
            if('1' == grid[rowIdx][columIdx])
            {
                ConverToZero(grid,rowIdx, columIdx, gridRowSize, gridColSize);
                Islands_Num++;
            }
        }
    }
    return Islands_Num;
    
}


void ConverToZero(char** grid, int rowIdx, int columIdx, int gridRowSize, int gridColSize)
{
    if( (rowIdx >= gridRowSize)||(columIdx >= gridColSize) ||(rowIdx < 0)||(columIdx < 0) )
        return;
    if('1' == grid[rowIdx][columIdx])
    {
        grid[rowIdx][columIdx] = '0';
    }
    else 
        return;
    ConverToZero(grid,rowIdx+1,columIdx, gridRowSize,gridColSize );
    ConverToZero(grid,rowIdx-1,columIdx, gridRowSize,gridColSize );
    
    ConverToZero(grid,rowIdx,columIdx+1, gridRowSize,gridColSize );
    ConverToZero(grid,rowIdx,columIdx-1, gridRowSize,gridColSize );
    
}

 

、、、、、、、、、、、、时隔1年,闷头做出My accepted Answer2、、、、、、、、、、、、、、

遍历整个数组,发现1则以此处为基准不断向右,向下扩展去找相邻的1。同时,将被访问过的位置进行标记。

#pragma once
#include <iostream>
#include <vector>
class calIsland
{
public:
	calIsland();
	~calIsland();

	
	std::vector<int> vInt;
	int mColumSize = 0;
	int mRowSize = 0;

	void setArray(std::vector<int>& array,int rowSize, int columSize)
	{
		vInt = array;
		mColumSize = columSize;
		mRowSize = rowSize;
	}

	void prinArray()
	{
		for (int i = 0; i < mRowSize;++i)
		{
			for (int j = 0; j < mColumSize; ++j)
			{
				std::cout << " " << getVal(i,j);
			}
			std::cout << std::endl;
		}
	}
	int getVal(int rowIdx, int columIdx)
	{
		int idx = mColumSize * rowIdx + columIdx;
		return vInt.at(idx);
	}

	void mark(int rowIdx, int columIdx)
	{
		int idx = mColumSize * rowIdx + columIdx;
	    vInt[idx] = -1;
	}
	int expand(int i, int j)
	{
		if (i >= mRowSize || j >= mColumSize)
		{
			return 0;
		}

		if (-1 == getVal(i, j))
		{
			return 0;
		}

		int val = getVal(i, j);
		mark(i,j);

		if (0 == val)
		{
			return 0;
		}
		expand(i+1,j);
		expand(i , j + 1);

		return 1;
	}

	int solve()
	{
		int res = 0;
		for (int i = 0; i < mRowSize; ++i)
		{
			for (int j = 0; j < mColumSize; ++j)
			{
				res += expand(i,j);
			}
			
		}
		return res;
	}
};

 

验证:

calIsland callIsLandObj;

std::vector<int> array = {1,1,0,0,1,1,0,0,0,0,1,0,1,1,0,1};
callIsLandObj.setArray(array, 4,4);
callIsLandObj.prinArray();
std::cout << "res="<<callIsLandObj.solve()<<std::endl;



2020.04

void expand(const vector<vector<int>>& arr, vector<vector<bool>> &mark, int row, int column,int i,int j) {
	if (i >= row) {
		return;
	}
	if (j >= column) {
		return;
	}
	mark[i][j] = true;

	if (j+1< column && arr[i][j + 1]){
		expand(arr,mark,row, column,i,j+1);
	}
	if ( i+1<row &&arr[i+1][j]) {
		expand(arr,mark, row, column, i+1, j);
	}
}

int calIsland(const vector<vector<int>>& arr, int row, int column) {
	if (arr.empty())
		return 0;
	int num = 0;
	vector<vector<bool>> mark(row, vector<bool>(column,false));//true: has been accessed.

	for (int i = 0; i < row; ++i) {
		for (int j = 0; j < column; ++j) {
			//mark[i][j] = true;
			if (arr[i][j] == 1 && !mark[i][j]) {
				num++;
				expand(arr,mark,row,column, i, j);
			}
		}
	}
	return num;
}
int main() {
	vector<vector<int>> arr(3, vector<int>(3, 0));
	arr[0][0] = 1; arr[0][1] = 1; arr[0][2] = 0;
	arr[1][0] = 0; arr[1][1] = 1; arr[1][2] = 1;
	arr[2][0] = 0; arr[2][1] = 0; arr[2][2] = 1;
	
	int num = calIsland(arr,3,3);
	return 1;
}

 



找出由‘1’组成的孤岛的bounding box

以一个m*n矩阵的方式给出一个黑白图像(1代表黑,0代表白),需要用长方形框出所有联通的黑色物体,任何一个像素和其上下左右四个像素是联通的。用(x, y)代表一个像素,x为行编号,第一行为0,向下递增,y为列编号,第一列为0,向右递增。长方形用左上像素坐标和右下像素坐标表示。

比如下面这个4*9的图:

000111011

001110001

001001001

001000111

有3个框,((0,2), (3,5)),  ((2,5), (2,5)),  ((0,6), (3,8))。

 

要求写一个函数GetBoundingBox。 输入参数为int m, int n, int pic[][] 输出为std::vector<Box>, 其中,Box定义如下:

struct Box {

int min_x;

int min_y;

int max_x;

int max_y;

};

#include <iostream>
#include <vector>

using namespace std;

//以pic[stRow][stColu]为起始,找出1构成的区块。 递归。
void expand(int stRow, int stColu, int row, int column, vector<vector<int>>& pic,
	int& leftCol, int& righCol, int& topRow, int& bottRow, vector<vector<bool>>& mark) {
	if (mark[stRow][stColu]) // 如果已经被访问过,则直接返回,因为后面有四个if,是向四个方向发散的
		return;
	mark[stRow][stColu] = true;
	if (stRow + 1< row && pic[stRow + 1][stColu]) {//下方的元素如果是1,则以下方的元素为始,继续递归
		expand(stRow + 1, stColu,  row,  column, pic,
			 leftCol,  righCol, topRow,  bottRow,  mark);
		if(bottRow< stRow + 1) //更新bottRow
		    bottRow = stRow + 1;
	}
	if (stColu + 1< column && pic[stRow][stColu+1]) {
		expand(stRow , stColu + 1, row, column, pic,
			leftCol, righCol, topRow, bottRow, mark);
		if(righCol< stColu + 1)
		    righCol = stColu + 1;
	}

	if (stRow - 1 >=0&&pic[stRow-1][stColu]) {
		expand(stRow-1, stColu, row, column, pic,
			leftCol, righCol, topRow, bottRow, mark);
		if(topRow > stRow - 1)
		  topRow = stRow - 1;
	}
	if (stColu - 1 >=0&&pic[stRow][stColu - 1]) {
		expand(stRow, stColu - 1, row, column, pic,
			leftCol, righCol, topRow, bottRow, mark);
		if(leftCol > stColu - 1)
		    leftCol = stColu - 1;
	}
}

//pic: 二维数组
//row: 数组的行数
//column:数组的列数
std::vector<Box> GetBoundingBox(int row, int column, vector<vector<int>>& pic) {
	vector<vector<bool>> mark(row, vector<bool>(column, false));//mark[i][j] == true, when pic[i][j] has been visited!
	std::vector<Box> resultVec;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < column; j++) {
			if (!mark[i][j] && pic[i][j]) { //如果mark[i][j]没有被访问过,且,pic[i,j]=1,则开始以此元素为始,找出相连接的1的区块
				int leftCol = j;//区块的最左侧元素的列
				int righCol = j;
				int topRow = i;//区块的最上方元素的行
				int bottRow = i;
				expand(i,j, row,column,pic, leftCol, righCol, topRow, bottRow, mark);
				Box ob;
				ob.min_x = topRow;
				ob.max_x = bottRow;
				ob.min_y = leftCol;
				ob.max_y = righCol;
				resultVec.push_back(std::move(ob));
			}
		}
	}
	return resultVec;
}

Test:

int main() {
	vector<vector<int>> vec(4, vector<int>(9,0));
	int row = 0;
	vec[row][0] = 0; vec[row][1] = 0; vec[row][2] = 0; vec[row][3] = 1; vec[row][4] = 1; vec[row][5] = 1; vec[row][6] = 0; vec[row][7] = 1; vec[row][8] = 1;
	row = 1; 
	vec[row][0] = 0; vec[row][1] = 0; vec[row][2] = 1; vec[row][3] = 1; vec[row][4] =1; vec[row][5] = 0; vec[row][6] = 0; vec[row][7] = 0; vec[row][8] = 1;
	row = 2; 
	vec[row][0] = 0; vec[row][1] = 0; vec[row][2] = 1; vec[row][3] = 0; vec[row][4] = 0; vec[row][5] = 1; vec[row][6] = 0; vec[row][7] = 0; vec[row][8] = 1;
	row = 3; 
	vec[row][0] = 0; vec[row][1] = 0; vec[row][2] = 1; vec[row][3] = 0; vec[row][4] = 0; vec[row][5] = 0; vec[row][6] = 1; vec[row][7] =1; vec[row][8] = 1;
	
	std::vector<Box> boxes = GetBoundingBox(4, 9, vec);

	for (const auto& it : boxes) {
		cout << "topLeftPoint.x =" << it.min_x << " topLeftPoint.y =" << it.min_y 
			<< " rightBottomPoint.x =" << it.max_x << " rightBottomPoint.y =" << it.max_y;
		cout << endl;
	}

}

 ouput:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

First Snowflakes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值