成都seo排名,简述搜索引擎优化的方法,php做企业网站管理系统,中国贸易网登录【问题描述】
你现在手里有一份大小为 N x N 的『地图』#xff08;网格#xff09; grid#xff0c;上面的每个『区域』#xff08;单元格#xff09;都用 0 和 1 标记好了。其中 0 代表海洋#xff0c;1 代表陆地#xff0c;你知道距离陆地区域最远的海洋区域是是哪一…【问题描述】
你现在手里有一份大小为 N x N 的『地图』网格 grid上面的每个『区域』单元格都用 0 和 1 标记好了。其中 0 代表海洋1 代表陆地你知道距离陆地区域最远的海洋区域是是哪一个吗请返回该海洋区域到离它最近的陆地区域的距离。我们这里说的距离是『曼哈顿距离』 Manhattan Distance(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| |y0 - y1| 。如果我们的地图上只有陆地或者海洋请返回 -1。示例 1
输入[[1,0,1],[0,0,0],[1,0,1]]
输出2提示1 grid.length grid[0].length 100
grid[i][j] 不是 0 就是 1
示例 1 输入[[1,0,1],[0,0,0],[1,0,1]] 输出2 解释 海洋区域 (1, 1) 和所有陆地区域之间的距离都达到最大最大距离为 2。
【解答思路】
1. 威威的工程BFS
多个陆地起点入队列 弹出的同时向四周摸索每次距离1
时间复杂度O(N^2) 空间复杂度O(N^2) public int maxDistance(int[][] grid) {//方向向量int [][] directions {{1,0},{-1,0},{0,1},{0,-1}};int N grid.length;QueueInteger queue new LinkedList();for(int i 0 ; i N; i){for(int j 0 ; j N; j){if(grid[i][j]1){queue.add(getIndex(i,j,N));}} }int size queue.size();//全部是0或者全部是1 全海洋或全陆地if(size0 || size N*N){return -1;}int step 0;while (!queue.isEmpty()){int currentQueueSize queue.size();for(int i0 ;icurrentQueueSize;i){Integer head queue.poll();//巧妙一个数存放一个二维坐标int currentX head / N;int currentY head % N;for(int[] direction :directions){int newX currentXdirection[0];int newY currentYdirection[1];if(inArea(newX,newY,N) grid[newX][newY]0){//扩充海洋部分 赋值任何非0数 最后只关注最长路径grid[newX][newY] 1;queue.add(getIndex(newX,newY,N));}}}step;}//最后一部没有扩散 但step仍然执行 故最后结果需要-1return step-1;}/*** param x 二维表格单元格横坐标* param y 二维表格单元格纵坐标* param cols 二维表格列数* return*/private int getIndex(int x, int y, int cols) {return x * cols y;}/*** param x 二维表格单元格横坐标* param y 二维表格单元格纵坐标* param N 二维表格行数列数* return 是否在二维表格有效范围内*/private boolean inArea(int x, int y, int N) {return 0 x x N 0 y y N;}
作者liweiwei1419
链接https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/yan-du-you-xian-bian-li-java-by-liweiwei1419/###### 2. 甜姨的刀法BFS
多个陆地起点入队列 弹出的同时向四周摸索每次距离1
时间复杂度O(N^2) 空间复杂度O(N^2) public int maxDistance(int[][] grid) {int[] dx {0, 0, 1, -1};int[] dy {1, -1, 0, 0};Queueint[] queue new ArrayDeque();int m grid.length, n grid[0].length;// 先把所有的陆地都入队。for (int i 0; i m; i) {for (int j 0; j n; j) {if (grid[i][j] 1) {queue.offer(new int[] {i, j});}}}// 从各个陆地开始一圈一圈的遍历海洋最后遍历到的海洋就是离陆地最远的海洋。boolean hasOcean false;int[] point null;while (!queue.isEmpty()) {point queue.poll();int x point[0], y point[1];// 取出队列的元素将其四周的海洋入队。for (int i 0; i 4; i) {int newX x dx[i];int newY y dy[i];if (newX 0 || newX m || newY 0 || newY n || grid[newX][newY] ! 0) {continue;}grid[newX][newY] grid[x][y] 1; // 这里我直接修改了原数组因此就不需要额外的数组来标志是否访问hasOcean true;queue.offer(new int[] {newX, newY});}}// 没有陆地或者没有海洋返回-1。if (point null || !hasOcean) {return -1;}// 返回最后一次遍历到的海洋的距离。return grid[point[0]][point[1]] - 1;}作者sweetiee
链接https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/jian-dan-java-miao-dong-tu-de-bfs-by-sweetiee/【总结】
1. BFS
如果题目要求返回的结果和距离相关需要在 while 循环内部一下子把当前列表的所有元素都依次取出来这种「一下子」操作的次数就是我们需要的距离如果一个单元格被添加到队列以后需要马上将它标记为已经访问根据情况可以直接在原始输入数组上修改也可以使用一个布尔数组 visited 进行标记否则很可能会出现死循环
2.树与无向图的BFS
树只有一个root 无向图有多个源点树是有向的 不需要标注是否访问过无向图需要标记是否访问过且需要在入队之前设置为已访问防止节点重复入队
3. 二维表格上编码代码的常用技巧
设置方向数组
int[][] directions {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};int[] dx {0, 0, 1, -1};
int[] dy {1, -1, 0, 0};设置是否越界的判断函数 inArea()根据情况使用二维坐标和一维坐标相互转换的操作因为二维坐标传入队列的时候需要封装成数组创建和销毁数组有一定性能消耗
private int getIndex(int x, int y, int cols) {return x * cols y;}