一、Problem
Given a m x n grid. Each cell of the grid has a sign pointing to the next cell you should visit if you are currently in this cell. The sign of grid[i][j] can be:
1 which means go to the cell to the right. (i.e go from grid[i][j] to grid[i][j + 1])
2 which means go to the cell to the left. (i.e go from grid[i][j] to grid[i][j - 1])
3 which means go to the lower cell. (i.e go from grid[i][j] to grid[i + 1][j])
4 which means go to the upper cell. (i.e go from grid[i][j] to grid[i - 1][j])
Notice that there could be some invalid signs on the cells of the grid which points outside the grid.
You will initially start at the upper left cell (0,0). A valid path in the grid is a path which starts from the upper left cell (0,0) and ends at the bottom-right cell (m - 1, n - 1) following the signs on the grid. The valid path doesn’t have to be the shortest.
You can modify the sign on a cell with cost = 1. You can modify the sign on a cell one time only.
Return the minimum cost to make the grid have at least one valid path.
Input: grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
Output: 3
Explanation: You will start at point (0, 0).
The path to (3, 3) is as follows. (0, 0) --> (0, 1) --> (0, 2) --> (0, 3)
change the arrow to down with cost = 1 --> (1, 3) --> (1, 2) --> (1, 1) --> (1, 0)
change the arrow to down with cost = 1 --> (2, 0) --> (2, 1) --> (2, 2) --> (2, 3)
change the arrow to down with cost = 1 --> (3, 3)
The total cost = 3.
二、Solution
方法一:dijkstra
- 限制条件是改变网格中的原有方向,则花费 cost 会加 1
- 转化为图论问题会简化很多:把每个格子看做是一个结点,结点之间连上不超过 4 条边(上下左右)
- 如果当前方向与轮回方向不同则将花费加 1,然后在添加到队列中。
未知错误:不知道为什么总是求不出答案… 哪里有问题?
class Solution {
final static int[][] dir = { {1,0},{0,-1},{0,1},{-1,0} };
int R, C, d[], INF = 0x3f3f3f3f;
boolean[] seen;
void dijstra(int[][] g) {
Queue<Pos> q = new PriorityQueue<>((e1, e2) -> e1.cost - e2.cost);
q.add(new Pos(0, 0));
seen[0] = true;
d[0] = 0;
while (!q.isEmpty()) {
Pos t = q.poll();
int x = t.pos / R, y = t.pos % R;
for (int k = 0; k < 4; k++) {
int tx = x + dir[k][0], ty = y + dir[k][1], tp = tx * R + ty;
if (tx < 0 || tx >= R || ty < 0 || ty >= C || seen[tp])
continue;
int tv = t.cost + (g[x][y] == k+1 ? 0 : 1);
if (tv < d[tp]) {
d[tp] = tv;
q.add(new Pos(tp, tv));
seen[tp] = true;
}
}
}
}
public int minCost(int[][] grid) {
R = grid.length; C = grid[0].length;
d = new int[R * C]; seen = new boolean[R * C];
Arrays.fill(d, INF);
dijstra(grid);
// for (int i : d) System.out.print(i);
return d[R*C-1];
}
class Pos {
int pos, cost;
Pos(int pos, int cost) {
this.pos = pos; this.cost = cost;
}
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,