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)
}
[圖片上傳失敗...(image-acb7b2-1683987963031)]
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;
}
}
[圖片上傳失敗...(image-3622c0-1683987963031)]
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;
}
[圖片上傳失敗...(image-f58052-1683987963031)]
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;
}
[圖片上傳失敗...(image-84090e-1683987963031)]