编程实现:leetcode_1162-- 地图分析

你现在手里有一份大小为 N x N 的「地图」(网格) grid,上面的每个「区域」(单元格)都用 0 和 1 标记好了。其中 0
代表海洋,1 代表陆地,请你找出一个海洋区域,这个海洋区域到离它最近的陆地区域的距离是最大的。
我们这里说的距离是 「曼哈顿距离」(> Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| + |y0 -> y1| 。

这道题我的思路是:
以0那点为中心,向两边搜索,比较求最短距离。
假设(x,y)这点为 ‘0’;
第一步:固定y不动,上下移动x,寻找 ‘1’,当找到第一个1的时候,直接跳出循环,节省运行时间。在(x,y)正上下方搜索。

第二步:向(x,y)两侧进行搜索, 寻找 ‘1’。
(1) 左侧, 左侧又分为左上部分和左下部分。
同样,也是固定y,来移动x。
左上部分: (x-j,y-1)·······(x-j,y-i)- - - i,j表示从0开始的值
左下部分: (x+j,y-1)·······(x+j,y-i)- - - i,j表示从0开始的值
(2)右侧相同。

第三步:比较这几部分中到(x,y)的距离,取最小值。

第四步:寻找一个最大值,也就是让全部 '0’执行上面三步,得到的值,取其中最大的那个,即为所求值。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int find_min(int arr[][3], int sz_row, int sz_col,int x,int y)
//这个函数是求一个0到1的最小距离。
{
	int i = 0;
	int j = 0;
	int ret = 0;
	int a = 0;
	int b = 0;
	for (i = 1; x - i  >= 0 || x + i < sz_row; i++)
	//y不变,在'0'的正上下方搜'1'
	{
		if (x - i >= 0)
		{
			if (arr[x - i][y] == 1)
			{
				ret = i;
				break;
			}	
		}
		if ( x + i < sz_row)
		{
			if (arr[x + i][y] == 1)
			{
				ret = i;
				break;
			}
		}
	}
	for (i = 1; y-i >=0 ; i++)//在左半部分搜'1' -- 固定y,移动x
	{
		for (j = 0; x-j>=0 || x+j<sz_row; j++)
		{
			if ( x - j >= 0)//左上部分
			{
				if (arr[x - j][y - i] == 1)
				{
					a = i + j;
					break;
				}
			}
			if (x + j < sz_row)//左下部分
			{
				if (arr[x + j][y - i] == 1)
				{
					a = i + j;
					break;
				}
			}
		}
		if (b<a && b == 0)//保留左部分的最小值
		{
			b = a;
		}
		else if (b>a)
		{
			b = a;
		}
	}
	if ((b < ret || ret == 0) && b != 0)//保留小的值
	{
		ret = b;
	}
	a = 0;
	b = 0;
	for (i = 1; y + i<sz_col; i++) //在右半部分搜'1' --固定y,移动x
	{
		for (j = 0; x - j>=0 || x + j<sz_row; j++)//右上部分
		{
			if (x - j >= 0)
			{
				if (arr[x - j][y + i] == 1)
				{
					a = i + j;
					break;
				}
			}
			if (x + j < sz_row)//右下部分
			{
				if (arr[x + j][y + i] == 1)
				{
					a = i + j;
					break;
				}
			}
		}
		if (b<a && b == 0)//保留右部分的最小值
		{
			b = a;
		}
		else if (b>a)
		{
			b = a;
		}
	}
	if ((b < ret || ret == 0) && b != 0)//保留小的值
	{
		ret = b;
	}
	return ret;
}

int maxDistance(int grid[][3], int gridSize, int* gridColSize)
{
	int i = 0;
	int j = 0;
	int ret = 0;
	int a = 0;
	for (i = 0; i < gridSize; i++)
	{
		for (j = 0; j < *gridColSize; j++)
		{
			if (grid[i][j] == 0)//找'0'
			{
				a = find_min(grid, gridSize, *gridColSize,i,j);
				if (ret < a)//保留距离远的值
				{
					ret = a;
				}
			}
		}
	}
	if (ret == 0)//ret = 0 证明全是0或者1
	{
		return -1;
	}
	else
		return ret;
}

int main()
{
	int arr[][3] = { { 1, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
	int a = sizeof(arr) / sizeof(arr[0]);
	int b = sizeof(arr[0]) / sizeof(arr[0][0]);
	int ret = maxDistance(arr, a, &b);
	printf("%d\n", ret);
	return 0;
}

本人菜鸟,这段代码还能优化,把左边和右边合并在一起写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值