一、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;
}
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,