This is graph and look for the shortest path, so BFS should be solution.
But how to handle K? We can look K as a parameter of every node.
My first solution use two Queues to solve it, one for node in grid, another one for remain number of nodes that can be removed.
But later I found that using one Queue can do it. The time complexity is O(m*n*k).
public int shortestPath(int[][] grid, int k) { int[][] dirs = new int[][]{{0, 1},{-1,0},{0, -1},{1, 0}}; int m= grid.length; int n=grid[0].length; Queue<int[]> queue = new LinkedList<>(); boolean[][][] visited= new boolean[m][n][k+1]; queue.offer(new int[]{0,0,k}); visited[0][0][k]=true; int steps=0; while(!queue.isEmpty()){ int size = queue.size(); for(int i=0;i<size;i++){ int[] node = queue.poll(); int x = node[0]; int y=node[1]; int curK = node[2]; if(x==m-1 && y==n-1) return steps; for(int[] dir:dirs){ int newX = x+dir[0]; int newY = y+dir[1]; if(newX<0|| newX>=m || newY<0||newY>=n) continue; int cellValue = grid[newX][newY]; if(cellValue==0){ if( visited[newX][newY][curK]) continue; queue.offer(new int[]{newX, newY, curK}); visited[newX][newY][curK]=true; }else{ if(curK==0 || visited[newX][newY][curK-1]) continue; queue.offer(new int[]{newX, newY,curK-1}); visited[newX][newY][curK-1]=true; } } } steps++; } return -1; }
We can make short codes:
public int shortestPath(int[][] grid, int k) { int[][] dirs = new int[][]{{0, 1},{-1,0},{0, -1},{1, 0}}; int m= grid.length; int n=grid[0].length; Queue<int[]> queue = new LinkedList<>(); boolean[][][] visited= new boolean[m][n][k+1]; queue.offer(new int[]{0,0,k}); //k is the remain obstacles you can remove visited[0][0][k]=true; //k is the remain obstacles you can remove int steps=0; while(!queue.isEmpty()){ int size = queue.size(); for(int i=0;i<size;i++){ int[] node = queue.poll(); int x = node[0]; int y=node[1]; int curK = node[2]; if(x==m-1 && y==n-1) return steps; for(int[] dir:dirs){ int newX = x+dir[0]; int newY = y+dir[1]; int newK = curK; if(newX<0|| newX>=m || newY<0||newY>=n) continue; int cellValue = grid[newX][newY]; if(cellValue==1){ newK--; } if(newK<0||visited[newX][newY][newK]) continue; visited[newX][newY][newK] = true; queue.offer(new int[]{newX, newY, newK}); } } steps++; } return -1; }