Leetcode1368. 使网格图至少有一条有效路径的最小代价-----Dijkstra 算法、BFS

题目表述

给你一个 m x n 的网格图 grid 。 grid 中每个格子都有一个数字,对应着从该格子出发下一步走的方向。 grid[i][j] 中的数字可能为以下几种情况:

  • 1 ,下一步往右走,也就是你会从 grid[i][j] 走到 grid[i][j + 1]
  • 2 ,下一步往左走,也就是你会从 grid[i][j] 走到 grid[i][j - 1]
  • 3 ,下一步往下走,也就是你会从 grid[i][j] 走到 grid[i + 1][j]
  • 4 ,下一步往上走,也就是你会从 grid[i][j] 走到 grid[i - 1][j]
    注意网格图中可能会有 无效数字 ,因为它们可能指向 grid 以外的区域。

一开始,你会从最左上角的格子 (0,0) 出发。我们定义一条 有效路径 为从格子 (0,0) 出发,每一步都顺着数字对应方向走,最终在最右下角的格子 (m - 1, n - 1) 结束的路径。有效路径 不需要是最短路径 。

你可以花费 cost = 1 的代价修改一个格子中的数字,但每个格子中的数字 只能修改一次 。

请你返回让网格图至少有一条有效路径的最小代价。

示例:
输入:grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
输出:3
解释:你将从点 (0, 0) 出发。
到达 (3, 3) 的路径为: (0, 0) --> (0, 1) --> (0, 2) --> (0, 3) 花费代价 cost = 1 使方向向下 --> (1, 3) --> (1, 2) --> (1, 1) --> (1, 0) 花费代价 cost = 1 使方向向下 --> (2, 0) --> (2, 1) --> (2, 2) --> (2, 3) 花费代价 cost = 1 使方向向下 --> (3, 3)
总花费为 cost = 3.

0-1广度优先搜索

多源BFS:从多个节点出发,每个节点入队一次,用size记录每一层的节点数,一次访问每一层的节点。多个路径同时搜索。
普通BFS:从单个节点出发,每个节点入队一次,直到找到路径
0-1BFS:在常规的广度优先搜索中,每个节点最多被添加进队列一次,而在 0-1 广度优先搜索中,每个节点最多被添加进双端队列两次(即队首一次,队尾一次)。因为我们求的是最短路径,所以当第一次出队列时,就将该节点标记为已读,第二次出队列时就不用再处理了。英雌需要用到visited数组记录,和Dijkstra 算法很相似。

class Solution { public int minCost(int[][] grid) { int m = grid.length; int n = grid[0].length; Deque<int[]> que = new ArrayDeque<>(); que.add(new int[]{0,0}); int[][] dirs = new int[][]{{0,1},{0,-1},{1,0},{-1,0}}; int[][] dis = new int[m][n]; for(int i = 0; i < m;i++){ Arrays.fill(dis[i], Integer.MAX_VALUE); } dis[0][0] = 0; boolean[][] visited = new boolean[m][n]; while(!que.isEmpty()){ int[] cur = que.poll(); int curx = cur[0]; int cury = cur[1]; if(visited[curx][cury]) continue; visited[curx][cury] = true; int i = 1; for (int[] dir:dirs){ int x = dir[0] + curx; int y = dir[1] + cury; if(x < 0 || y<0|| x >= m || y>=n) continue; int cost = i == grid[curx][cury] ? 0 : 1; if(dis[curx][cury] + cost <= dis[x][y]) dis[x][y] = dis[curx][cury] + cost; else continue; if (cost == 0){ que.addFirst(new int[]{x,y}); }else{ que.addLast(new int[]{x,y}); } i++; } } return dis[m-1][n-1]; } }

Dijkstra 算法

class Solution { public int minCost(int[][] grid) { int m = grid.length; int n = grid[0].length; int[][] dis = new int[m][n]; for(int i = 0; i < m; i++){ Arrays.fill(dis[i], Integer.MAX_VALUE); } dis[0][0] = 0; boolean[][] visited = new boolean[m][n]; int[][] dirs = {{0,1}, {0,-1},{1,0}, {-1,0}}; PriorityQueue<int[]> que = new PriorityQueue<>((a,b)->{return a[2] - b[2];}); que.offer(new int[]{0,0,0}); while(!que.isEmpty()){ int[] cur = que.poll(); if(visited[cur[0]][cur[1]]) continue; visited[cur[0]][cur[1]] = true; for(int i = 1;i <= 4;i++){ int x = dirs[i-1][0] + cur[0]; int y = dirs[i-1][1] + cur[1]; if(x < 0 || y < 0 || x>= m || y>= n) continue; int cost = 0; if(i != grid[cur[0]][cur[1]]) cost = 1; if(cost + cur[2] < dis[x][y]){ dis[x][y] = cost + cur[2]; que.offer(new int[]{x,y,dis[x][y]}); } } } return dis[m-1][n-1]; } }

__EOF__

本文作者Younger
本文链接https://www.cnblogs.com/youngerwb/p/16342146.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   YoungerWb  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示