2023-05-13:你现在手里有一份大小为 n x n 的 网格 grid, 上面的每个 单元格 都用 0 和 1 标记好了其中 0 代表海洋,1 代表陆地。 请你找出一个海洋单元格,这个海洋单元格
2023-05-13:你现在手里有一份大小为 n x n 的 网格 grid,
上面的每个 单元格 都用 0 和 1 标记好了其中 0 代表海洋,1 代表陆地。
请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的,
并返回该距离。如果网格上只有陆地或者海洋,请返回 -1。
我们这里说的距离是「曼哈顿距离」( Manhattan Distance):
(x0, y0) 和 (x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1| 。
输入:grid = [[1,0,0],[0,0,0],[0,0,0]]。
输出:4。
答案2023-05-13:
大体步骤如下:
1.定义变量:
声明一个二维整数数组
grid表示网格,以及整数变量n和m表示网格的行数和列数;声明一个二维布尔数组
visited,用于记录每个单元格是否被访问过;声明一个二维整数数组
queue,用于存储队列中的每个元素;声明整数变量
l和r,分别表示队列的左右端点;声明整数变量
find,统计已经找到的海洋的数量;声明整数变量
seas,统计海洋的总数量;声明整数变量
distance,表示最深能找到的海洋层数,初始化为-1。
2.初始化变量:
将
l、r、find、seas和distance全部初始化为0或-1,将visited数组全部设为false;遍历整个网格,对于每个陆地单元格,将其标记为已访问,并将其加入队列中;对于每个海洋单元格,将
seas增加1。
3.进行BFS搜索:
当队列不为空时,取出队列中所有元素进行处理,直到找到所有的海洋单元格;
对于每个队列元素,将其四周的海洋单元格加入队列中,并标记为已访问;同时统计找到的海洋单元格数量,并将
distance加1。
4.返回结果:
如果没有找到任何海洋或者陆地,则返回-1;
否则,返回
distance。
时间复杂度:
初始化visited数组、queue数组和一些变量的时间复杂度是O(n^2),其中n为网格边长;
遍历整个网格的时间复杂度也是O(n^2);
BFS搜索的时间复杂度最坏情况下是O(n^2),因为最多需要遍历整个网格。
因此,总的时间复杂度是O(n^2)。
空间复杂度:
visited数组的空间复杂度是O(n^2);
queue数组的空间复杂度是O(n^2);
其他变量占用常数空间。
因此,总的空间复杂度是O(n^2)。
go语言完整代码如下:
package main
var queue [10000][2]int
var l int
var r int
var visited [100][100]bool
var find int
func maxDistance(grid [][]int) int {
// 清空变量
l = 0
r = 0
find = 0
n := len(grid)
m := len(grid[0])
// 清空visited
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
visited[i][j] = false
}
}
// 大体思路 :
// 1) 先把所有的陆地加入队列,并且统计一共有多少海洋
seas := 0
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if grid[i][j] == 1 {
visited[i][j] = true
queue[r][0] = i
queue[r][1] = j
r++
} else {
seas++
}
}
}
// 2) 从陆地开始广播出去(bfs),每一块陆地的上、下、左、右所能找到的海洋都是第一层海洋
// 3) 第一层海洋继续bfs,每一块海洋的上、下、左、右所能找到的海洋都是第二层海洋
// 4) 第二层海洋继续bfs,每一块海洋的上、下、左、右所能找到的海洋都是第三层海洋
// ...
// 也就是说,以陆地做起点,每一层bfs都只找海洋!
// 看看最深能找到多少层海洋
distance := -1 // 这个变量就是最深的海洋层数
for l < r && find < seas { // find < seas说明所有的海洋块没有找全,继续找!
size := r - l
for i := 0; i < size && find < seas; i++ {
row := queue[l][0]
col := queue[l][1]
add(row-1, col, n, m, grid)
add(row+1, col, n, m, grid)
add(row, col-1, n, m, grid)
add(row, col+1, n, m, grid)
l++
}
distance++
}
if find == 0 {
return -1
}
return distance + 1
}
func add(i int, j int, n int, m int, grid [][]int) {
if i >= 0 && i < n && j >= 0 && j < m && grid[i][j] == 0 && !visited[i][j] {
find++
visited[i][j] = true
queue[r][0] = i
queue[r][1] = j
r++
}
}
func main() {
grid := [][]int{{1, 0, 1}, {0, 0, 0}, {1, 0, 1}}
result := maxDistance(grid)
println(result)
grid = [][]int{{1, 0, 0}, {0, 0, 0}, {0, 0, 0}}
result = maxDistance(grid)
println(result)
}

rust语言完整代码如下:
static mut QUEUE: [[i32; 2]; 10000] = [[0; 2]; 10000];
static mut L: usize = 0;
static mut R: usize = 0;
static mut VISITED: [[bool; 100]; 100] = [[false; 100]; 100];
static mut FIND: i32 = 0;
fn main() {
let grid = vec![vec![1, 0, 1], vec![0, 0, 0], vec![1, 0, 1]];
unsafe {
let ans = max_distance(grid);
println!("ans = {}", ans);
}
let grid = vec![vec![1, 0, 0], vec![0, 0, 0], vec![0, 0, 0]];
unsafe {
let ans = max_distance(grid);
println!("ans = {}", ans);
}
}
unsafe fn max_distance(grid: Vec<Vec<i32>>) -> i32 {
// 清空变量
// 只要l = 0,r = 0,队列就算被清空了
L = 0;
R = 0;
FIND = 0;
let n = grid.len();
let m = grid[0].len();
// 清空visited
for i in 0..n {
for j in 0..m {
VISITED[i][j] = false;
}
}
// 初始化队列
let mut queue: [[i32; 2]; 10000] = [[0; 2]; 10000];
// 大体思路 :
// 1) 先把所有的陆地加入队列,并且统计一共有多少海洋
let mut seas = 0;
for i in 0..n {
for j in 0..m {
if grid[i][j] == 1 {
VISITED[i][j] = true;
queue[R][0] = i as i32;
queue[R][1] = j as i32;
R += 1;
} else {
seas += 1;
}
}
}
// 2) 从陆地开始广播出去(bfs),每一块陆地的上、下、左、右所能找到的海洋都是第一层海洋
// 3) 第一层海洋继续bfs,每一块海洋的上、下、左、右所能找到的海洋都是第二层海洋
// 4) 第二层海洋继续bfs,每一块海洋的上、下、左、右所能找到的海洋都是第三层海洋
// ...
// 也就是说,以陆地做起点,每一层bfs都只找海洋!
// 看看最深能找到多少层海洋
let mut distance = 0; // 这个变量就是最深的海洋层数
while L < R && FIND < seas {
// find < seas说明所有的海洋块没有找全,继续找!
let size = R - L;
for i in 0..size {
if FIND >= seas {
break;
}
let row = queue[L][0];
let col = queue[L][1];
add(row - 1, col, n, m, grid.clone(), &mut queue);
add(row + 1, col, n, m, grid.clone(), &mut queue);
add(row, col - 1, n, m, grid.clone(), &mut queue);
add(row, col + 1, n, m, grid.clone(), &mut queue);
L += 1;
}
distance += 1;
}
if FIND == 0 {
return -1;
} else {
return distance;
}
}
unsafe fn add(
i: i32,
j: i32,
n: usize,
m: usize,
grid: Vec<Vec<i32>>,
queue: &mut [[i32; 2]; 10000],
) {
if i >= 0
&& i < n as i32
&& j >= 0
&& j < m as i32
&& grid[i as usize][j as usize] == 0
&& !VISITED[i as usize][j as usize]
{
FIND += 1;
VISITED[i as usize][j as usize] = true;
queue[R][0] = i;
queue[R][1] = j;
R += 1;
}
}

c语言完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 10000
int queue[MAX_SIZE][2];
int l;
int r;
bool visited[100][100];
int find;
void add(int i, int j, int n, int m, int** grid);
int maxDistance(int** grid, int gridSize, int* gridColSize) {
l = 0;
r = 0;
find = 0;
int n = gridSize;
int m = *gridColSize;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
visited[i][j] = false;
}
}
int seas = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 1) {
visited[i][j] = true;
queue[r][0] = i;
queue[r++][1] = j;
}
else {
seas++;
}
}
}
int distance = 0;
while (l < r && find < seas) {
int size = r - l;
for (int i = 0; i < size && find < seas; i++, l++) {
int row = queue[l][0];
int col = queue[l][1];
add(row - 1, col, n, m, grid);
add(row + 1, col, n, m, grid);
add(row, col - 1, n, m, grid);
add(row, col + 1, n, m, grid);
}
distance++;
}
return find == 0 ? -1 : distance;
}
void add(int i, int j, int n, int m, int** grid) {
if (i >= 0 && i < n && j >= 0 && j < m && grid[i][j] == 0 && !visited[i][j]) {
find++;
visited[i][j] = true;
queue[r][0] = i;
queue[r++][1] = j;
}
}
int main() {
int gridSize = 3;
int gridColSize[3] = { 3, 3, 3 };
int** grid = (int**)malloc(gridSize * sizeof(int*));
for (int i = 0; i < gridSize; i++) {
grid[i] = (int*)malloc(gridColSize[i] * sizeof(int));
}
grid[0][0] = 1;
grid[0][1] = 0;
grid[0][2] = 1;
grid[1][0] = 0;
grid[1][1] = 0;
grid[1][2] = 0;
grid[2][0] = 1;
grid[2][1] = 0;
grid[2][2] = 1;
int result = maxDistance(grid, gridSize, gridColSize);
printf("%d\n", result);
grid[0][0] = 1;
grid[0][1] = 0;
grid[0][2] = 0;
grid[1][0] = 0;
grid[1][1] = 0;
grid[1][2] = 0;
grid[2][0] = 0;
grid[2][1] = 0;
grid[2][2] = 0;
result = maxDistance(grid, gridSize, gridColSize);
printf("%d\n", result);
for (int i = 0; i < gridSize; i++) {
free(grid[i]);
}
free(grid);
return 0;
}

c++语言完整代码如下:
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int queue[10000][2];
int l;
int r;
bool visited[100][100];
int find0;
int maxDistance(vector<vector<int>>& grid) {
// 清空变量
// 只要l = 0,r = 0,队列就算被清空了
l = 0;
r = 0;
find0 = 0;
int n = grid.size();
int m = grid[0].size();
// 清空visited
memset(visited, false, sizeof(visited));
// 大体思路 :
// 1) 先把所有的陆地加入队列,并且统计一共有多少海洋
int seas = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 1) {
visited[i][j] = true;
queue[r][0] = i;
queue[r++][1] = j;
}
else {
seas++;
}
}
}
// 2) 从陆地开始广播出去(bfs),每一块陆地的上、下、左、右所能找到的海洋都是第一层海洋
// 3) 第一层海洋继续bfs,每一块海洋的上、下、左、右所能找到的海洋都是第二层海洋
// 4) 第二层海洋继续bfs,每一块海洋的上、下、左、右所能找到的海洋都是第三层海洋
// ...
// 也就是说,以陆地做起点,每一层bfs都只找海洋!
// 看看最深能找到多少层海洋
int distance = 0; // 这个变量就是最深的海洋层数
while (l < r && find0 < seas) { // find < seas说明所有的海洋块没有找全,继续找!
int size = r - l;
for (int i = 0; i < size && find0 < seas; i++, l++) {
int row = queue[l][0];
int col = queue[l][1];
if (row - 1 >= 0 && row - 1 < n && col >= 0 && col < m && grid[row - 1][col] == 0 && !visited[row - 1][col]) {
find0++;
visited[row - 1][col] = true;
queue[r][0] = row - 1;
queue[r++][1] = col;
}
if (row + 1 >= 0 && row + 1 < n && col >= 0 && col < m && grid[row + 1][col] == 0 && !visited[row + 1][col]) {
find0++;
visited[row + 1][col] = true;
queue[r][0] = row + 1;
queue[r++][1] = col;
}
if (row >= 0 && row < n && col - 1 >= 0 && col - 1 < m && grid[row][col - 1] == 0 && !visited[row][col - 1]) {
find0++;
visited[row][col - 1] = true;
queue[r][0] = row;
queue[r++][1] = col - 1;
}
if (row >= 0 && row < n && col + 1 >= 0 && col + 1 < m && grid[row][col + 1] == 0 && !visited[row][col + 1]) {
find0++;
visited[row][col + 1] = true;
queue[r][0] = row;
queue[r++][1] = col + 1;
}
}
distance++;
}
return find0 == 0 ? -1 : distance;
}
int main() {
vector<vector<int>> grid = { {1,0,1}, {0,0,0}, {1,0,1} };
cout << maxDistance(grid) << endl;
grid = { {1,0,0}, {0,0,0}, {0,0,0} };
cout << maxDistance(grid) << endl;
}

2023-05-13:你现在手里有一份大小为 n x n 的 网格 grid, 上面的每个 单元格 都用 0 和 1 标记好了其中 0 代表海洋,1 代表陆地。 请你找出一个海洋单元格,这个海洋单元格的更多相关文章
- 【leetcode-03】给定一个字符串,请你找出其中不含有重复字符的最长子串的长度
开个新坑,leetcode上面做题目.下面是题目描述: <!-- 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出 ...
- 笔试题&面试题:找出一个数组中第m小的值并输出
题目:找出一个数组中第m小的值并输出. 代码: #include <stdio.h> int findm_min(int a[], int n, int m) //n代表数组长度,m代表找 ...
- c语言题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点
//题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小.也可能没有鞍点. // #include "stdio.h" #include <stdli ...
- LeetCode练习3 找出一个字符串中最大不重复子字符串的长度
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...
- C语言程序,找出一个二维数组的鞍点。
什么是鞍点????? 鞍点就是在一个二维数组中,某一个数在该行中最大,然而其在该列中又是最小的数,这样的数称为鞍点. 昨天突然在书上看到这样的一道题,就自己尝试着写了一个找出一个二维数组中的鞍点. 好 ...
- Class 找出一个整形数组中的元素的最大值
目的:找出一个整形数组中的元素的最大值 以下,我们用类和对象的方法来做. #include<iostream> using namespace std; class Array_m ...
- Android系统,动态找出一个包下所有的类
最近在写一个android应用,由于针对不同机型功能很不同,为了隔离变化,希望将各项功能插件化,通过编译开关来控制不同版本的功能,而不是在代码中通过逻辑来判断. 我想了一个办法,用表驱动的方法,结合插 ...
- 平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。
题目:平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小. 源码如下: #include <iostream> #include <string.h> #incl ...
- [PY3]——找出一个序列中出现次数最多的元素/collections.Counter 类的用法
问题 怎样找出一个序列中出现次数最多的元素呢? 解决方案 collections.Counter 类就是专门为这类问题而设计的, 它甚至有一个有用的 most_common() 方法直接给了你答案 c ...
- C语言:找出一个大于给定整数m且紧随m的素数,-求出能整除x且不是偶数的数的个数,
//函数fun功能:找出一个大于给定整数m且紧随m的素数,并作为函数值返回. #include <stdlib.h> #include <conio.h> #include & ...
随机推荐
- Django框架项目——BBS项目介绍、表设计、表创建同步、注册、登录功能、登录功能、首页搭建、admin、头像、图片防盗、个人站点、侧边栏筛选、文章的详情页、点赞点踩、评论、后台管理、添加文章、头像
文章目录 1 BBS项目介绍.表设计 项目开发流程 表设计 2 表创建同步.注册.登录功能 数据库表创建及同步 注册功能 登陆功能 3 登录功能.首页搭建.admin.头像.图片防盗.个人站点.侧边栏 ...
- FreeRTOS 操作系统
FreeRTOS操作系统 01 FreeRTOS 的定义和概述 定义:FreeRTOS(Free-Real-Time Operating System)是一个开源的实时操作系统内核,专门为嵌入式系统设 ...
- python-手机自动化
摘取:https://www.byhy.net/tut/auto/appium/01/ 用途和特点 Appium 是一个移动 App (手机应用)自动化工具. 手机APP 自动化有什么用? 自动化完成 ...
- [SWPUCTF 2021 新生赛]老鼠走迷宫(详细版
附件下载 https://wwvc.lanzouj.com/iYLez1br84jg 解题思路 用pyinstxtrator解析exe 重点:将无后缀的5先修改后缀为pyc,然后随便找一个pyc文件补 ...
- chatgpt镜像站汇总 - 聚合GPT【即时更新】
自荐下由我开发的聚合GPT网站,这边的GPT镜像站均为免费.无登录.无次数限制的!会及时剔除失效.添加可用地址[欢迎STAR.PR] 地址:https://ele-cat.gitee.io/comp- ...
- 如何使用markdown
关于如何使用markdown写博客 markdown的语法 代码的插入 电脑Table建上面上面的键输入三个点``` 然后输入语言+回车 c语言中第一个程序 #include<stdio.h&g ...
- VUE首屏加载优化 性能优化分析插件安装分享
优化背景: 项目上线后 第一次进入项目要等待接近50s才能进入页面.一开始觉得是电脑配置问题或者网络问题.F12后发现加载资源过慢 其中一个chunk-***js文件有10m 加载了45s .我们使用 ...
- Ubuntu环境下C++使用onnxruntime和Opencv进行YOLOv8模型部署
目录 环境配置 系统环境 项目文件路径 文件环境 config.txt CMakeLists.txt type.names 读取config.txt配置文件 修改图片尺寸格式 读取缺陷标志文件 生成缺 ...
- Codeforces Round 905 (Div. 3)
Codeforces Round 905 (Div. 3) A. Morning 题意:操作:显示,向前走都为一次操作:目标:显示这四个数 思路:0->10,然后依次作差就行 #include ...
- 吉特日化MES实施--三种浪费
在实施吉特日化MES系统的过程中,遇到各种问题,包括自身问题以及甲方问题,导致项目滞后延期的主要问题分析,汇总三种浪费: (1) 信息传递的浪费: 这个在甲方产品设计以及生产过程中出现的问题,也是我 ...