1368. Minimum Cost to Make at Least One Valid Path in a Grid

问题:

给定n*m二维数组grid,要求从左上角(0,0)->右下角(n-1,m-1)

移动规则:grid[i][j]

1:right -> grid[i][j + 1]

2:left -> grid[i][j - 1]

3:down -> grid[i + 1][j]

4:up -> grid[i - 1][j]

若按照grid[i][j]所述的方式移动,无消耗。

否则可改变为余下的移动方向,则消耗为 1。

求要到达目标位置,最小消耗是多少。

Example 1:
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.

Example 2:
Input: grid = [[1,1,3],[3,2,2],[1,1,4]]
Output: 0
Explanation: You can follow the path from (0, 0) to (2, 2).

Example 3:
Input: grid = [[1,2],[4,3]]
Output: 1

Example 4:
Input: grid = [[2,2,2],[2,2,2]]
Output: 3

Example 5:
Input: grid = [[4]]
Output: 0
 

Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 100

  

example 1:

 

example 2:

 

 example 3:

 

 

 

解法:BFS,Dijkstra,priority queue

使用优先队列,权值为:cost

优先处理cost较小的状态。

 

  • 状态:cell坐标
    • visited也保存cell坐标,
      • ⚠️ 注意:但是由于可能会重复到达同一个坐标,cost不同,那么选择cost更小的路径,这里即用到了(从(0,0)到当前cell的)最短路径。
      • 因此visited保存:到对应cell的cost:unordered_map<int, int> //i*100+j, cost
    • queue里保存:权值cost,cell坐标 (i, j)
  • 对当前状态的处理:
    • 如果cell坐标==target,那么返回当前权值cost
    • 否则,进行下一步选择:
      • dir四个方向:若!=gird[当前cell坐标],cost++
      • 若next cell的visited中保存的cost更小,那么选择当前的路径到达next cell。更新visited[next cell]
      • 同时将next cell的状态push到优先队列中。

 

代码参考:

 1 class Solution {
 2 public:
 3     vector<vector<int>> dir = {{0,0},{0,1},{0,-1},{1,0},{-1,0}};
 4     int m,n;
 5     int minCost(vector<vector<int>>& grid) {
 6         n = grid.size();
 7         m = grid[0].size();
 8         priority_queue<pair<int, pair<int,int>>, vector<pair<int,pair<int,int>>>, greater<pair<int,pair<int,int>>>>q;
 9         //cost, {i,j}
10         unordered_map<int,int> visited;//i*100+j, cost
11         q.push({0,{0,0}});
12         visited[0]=0;
13         while(!q.empty()) {
14             auto [cur_cost, cur] = q.top();
15             q.pop();
16             //cout<<"pop: cost:"<<cur_cost<<"{x,y}: "<<cur.first<<","<<cur.second<<endl;
17             if(cur.first == n-1 && cur.second == m-1) return cur_cost;
18             for(int i=1; i<5; i++) {
19                 int x = cur.first+dir[i][0];
20                 int y = cur.second+dir[i][1];
21                 int cost = cur_cost;
22                 if(x<0 || y<0 || x>=n || y>=m) continue;
23                 if(grid[cur.first][cur.second]!=i) cost++;
24                 if(visited.count(x*100+y) == 0 || visited[x*100+y]>cost) {
25                     visited[x*100+y] = cost;
26                     q.push({cost, {x,y}});
27                     //cout<<"push: cost:"<<cost<<"{x,y}: "<<x<<","<<y<<endl;
28                 }
29             }
30         }
31         return m+n-2;
32     }
33 };

 

posted @ 2021-03-17 12:42  habibah_chang  阅读(81)  评论(0编辑  收藏  举报