1162. 地图分析
https://leetcode-cn.com/problems/as-far-from-land-as-possible/
实现代码(较长)
// 构造结构体。x:地图横坐标,y:地图纵坐标typedef struct Queue{ int x, y;}Queue;// 题目函数int maxDistance(int** grid, int gridSize, int* gridColSize){ // 分别表示圆心坐标的上下左右位置上的坐标 int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; // 声明一个结构体数组。用以模拟队列,存放图中的所有坐标点 Queue *queue = (Queue*)malloc(sizeof(Queue) * gridSize * gridSize); int qIndex = 0; //结构体数组的下标索引 int width = gridSize; int height = gridSize; // 获取所有陆地的坐标,并依次入队 for(int i = 0; i < width; i++){ for(int j = 0; j < height; j++){ if(grid[i][j] == 1){ queue[qIndex].x = i; queue[qIndex].y = j; qIndex++; } } } int hasOcean = 0; // 判断途中是否全为陆地或海洋 int point[2]; // 存放进行广度优先遍历的圆心坐标 for(int i = 0; i < gridSize*gridSize; i++){ point[0] = queue[i].x; point[1] = queue[i].y; int x = point[0]; int y = point[1]; // 遍历离圆心最近的坐标,即上下左右的坐标点 for(int j = 0; j < 4; j++){ int newX = x + dx[j]; int newY = y + dy[j]; // 如果坐标越界,或者坐标已经进行过了广度优先遍历,则遍历下一个坐标点 if(newX < 0 || newX >= width || newY < 0 || newY >= height || grid[newX][newY] != 0){ continue; } // 为没有遍历过的坐标赋值(离陆地的最近距离) // grid[x][y] 代表上一层遍历的坐标离陆地的距离 grid[newX][newY] = grid[x][y] + 1; hasOcean = 1; // 没有遍历过的坐标入队 queue[qIndex].x = newX; queue[qIndex].y = newY; qIndex++; } } // 判断是否全为陆地或海洋 if(point == NULL || !hasOcean) return -1; // 获取最后一个遍历的坐标,并获取其距离陆地的距离 return grid[point[0]][point[1]]-1;}
算法模仿地址
https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/jian-dan-java-miao-dong-tu-de-bfs-by-sweetiee/
实现思路
这题我并不会作,而且看到题目时我都不知该使用什么数据结构和算法来实现。在我学习了思路后,将作者的代码改写成了 C语言,并且用数组模拟了队列的操作。
这位作者是使用 BFS(广度优先遍历)的算法,和队列这个数据结构。
实现思路如下:
先遍历一遍地图,将所遍历到的陆地坐标存入队列中;
遍历队列:以队首的坐标为圆心,遍历其上下左右的坐标点,如果坐标越界或者该坐标已遍历,那么遍历下一个坐标点。判断坐标是否遍历的依据是,该坐标在地图中的值是否为 0;因为已经遍历过的坐标,我们会为其赋值(该点到陆地的距离);
判断地图是否全为海洋或陆地;
获取最后一次遍历的坐标点,并获取该坐标在地图中的值。最后一个遍历的坐标点,就是到离它最近的陆地单元格的距离最大的点,该坐标值减 1 就是离陆地最近的距离。
下面就是这个功能的算法实现图解。
第四张图的最大值为 4,也就是说这些值为 4 的点,离最近的陆地的距离最大,并且距离为 4-1=3。
图中数字相同的点,就是在 BFS(广度优先遍历)中处于同层的点。BFS 的算法思想也就是以一点为圆心,逐层向外遍历。