int m, n;int[][] dirs ={{0,1},{0,-1},{1,0},{-1,0}};publicintminCost(int[][] grid){
m = grid.length;
n = grid[0].length;int[] dist =newint[m * n];Arrays.fill(dist,Integer.MAX_VALUE);
dist[0]=0;boolean[] vis =newboolean[m * n];Deque<Integer> deque =newArrayDeque<>();
deque.offerFirst(0);while(!deque.isEmpty()){int cur_pos = deque.pollFirst();if(vis[cur_pos]){continue;}
vis[cur_pos]=true;int x = cur_pos / n, y = cur_pos % n;for(int i =0; i <4; i++){int nx = x + dirs[i][0], ny = y + dirs[i][1];int new_pos = nx * n + ny;//1:右 2:左 3:下 4:上//当前的[x,y]的值如果是符合1 2 3 4 的值,则不需要修改,也就是 0int new_dist = dist[cur_pos]+(grid[x][y]== i +1?0:1);if(nx <0|| nx >= m || ny <0|| ny >= n){continue;}if(new_dist < dist[new_pos]){
dist[new_pos]= new_dist;//01广度优先搜索,将0的那个点加入到队首,1的那个点加入到对尾if(grid[x][y]== i +1){
deque.offerFirst(new_pos);}else{
deque.offerLast(new_pos);}}}}return dist[m * n -1];}
另,不适用vis标记数组
int m, n;int[][] dirs ={{0,1},{0,-1},{1,0},{-1,0}};publicintminCost(int[][] grid){
m = grid.length;
n = grid[0].length;int[] dist =newint[m * n];Arrays.fill(dist,Integer.MAX_VALUE);
dist[0]=0;Deque<Integer> deque =newArrayDeque<>();
deque.offerFirst(0);while(!deque.isEmpty()){int cur_pos = deque.pollFirst();int x = cur_pos / n, y = cur_pos % n;for(int i =0; i <4; i++){int nx = x + dirs[i][0], ny = y + dirs[i][1];int new_pos = nx * n + ny;//1:右 2:左 3:下 4:上//当前的[x,y]的值如果是符合1 2 3 4 的值,则不需要修改,也就是 0int new_dist = dist[cur_pos]+(grid[x][y]== i +1?0:1);if(nx <0|| nx >= m || ny <0|| ny >= n){continue;}if(new_dist < dist[new_pos]){
dist[new_pos]= new_dist;//01广度优先搜索,将0的那个点加入到队首,1的那个点加入到对尾if(grid[x][y]== i +1){
deque.offerFirst(new_pos);}else{
deque.offerLast(new_pos);}}}}return dist[m * n -1];}
方法2:Dijkstra
classPoint{int dist;int r;int c;Point(){}Point(int dist,int r,int c){this.dist = dist;this.r = r;this.c = c;}}int[][] dirs =newint[][]{{0,1},{0,-1},{1,0},{-1,0}};publicintminCost(int[][] grid){int m = grid.length;int n = grid[0].length;boolean[][] vis =newboolean[m][n];int[][] dist =newint[m][n];for(int r =0; r < m; r++){Arrays.fill(dist[r],Integer.MAX_VALUE);}//按距离排序PriorityQueue<Point> pq =newPriorityQueue<>((o1, o2)-> o1.dist - o2.dist);
pq.offer(newPoint(0,0,0));
dist[0][0]=0;while(!pq.isEmpty()){Point cur = pq.poll();int d = cur.dist, r = cur.r, c = cur.c;if(vis[r][c]){continue;}
vis[r][c]=true;for(int k =0; k <4; k++){int nr = r + dirs[k][0], nc = c + dirs[k][1];int cost =(k +1== grid[r][c]?0:1);if(0<= nr && nr < m &&0<= nc && nc < n && dist[r][c]+ cost < dist[nr][nc]){
dist[nr][nc]= dist[r][c]+ cost;
pq.offer(newPoint(dist[nr][nc], nr, nc));}}}return dist[m -1][n -1];}
方法3:Dijkstra
int m, n;int[][] dirs ={{0,1},{0,-1},{1,0},{-1,0}};publicintminCost(int[][] grid){
m = grid.length;
n = grid[0].length;int[] dist =newint[m * n];Arrays.fill(dist,Integer.MAX_VALUE);boolean[] vis =newboolean[m * n];
dist[0]=0;PriorityQueue<Integer> pq =newPriorityQueue<>((a, b)-> dist[a]- dist[b]);
pq.offer(0);while(!pq.isEmpty()){//当前点位置int cur_pos = pq.poll();//注释掉下面的部分可以通过// if (vis[cur_pos]) {// continue;// }
vis[cur_pos]=true;//当前点的位置转化成坐标int x = cur_pos / n, y = cur_pos % n;for(int i =0; i <4; i++){int nx = x + dirs[i][0], ny = y + dirs[i][1];if(nx <0|| nx >= m || ny <0|| ny >= n){continue;}int new_pos = nx * n + ny;int new_dist = dist[cur_pos]+(grid[x][y]== i +1?0:1);if(new_dist < dist[new_pos]){
dist[new_pos]= new_dist;
pq.offer(new_pos);}}}return dist[m * n -1];}