【leetcode】1293 .Shortest Path in a Grid with Obstacles
You are given an m x n integer matrix grid where each cell is either 0 (empty) or 1 (obstacle). You can move up, down, left, or right from and to an empty cell in one step.
Return the minimum number of steps to walk from the upper left corner (0, 0) to the lower right corner (m - 1, n - 1) given that you can eliminate at most k obstacles. If it is not possible to find such walk return -1.
利用深度优先加回溯结果time Limited。。。
class Solution { public: int direction[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int res=INT_MAX; int shortestPath(vector<vector<int>>& grid, int k) { //这种题感觉就是递归回溯 但是有两个限制 一个是求最小步数(动态规划) 然后是求能够消除指定k个 障碍 //如果不ok就回溯一个 //lets have a try //好久没写bfs了 int m=grid.size(),n=grid[0].size(); vector<vector<int>> memo(m,vector<int>(n,0)); dfs(grid,memo,0,0,k,m,n,0); if(res==INT_MAX) return -1; return res; } bool inAera(int x,int y,int m,int n){ //judge aera return x>=0 &&x<m &&y>=0 &&y<n; } void dfs(vector<vector<int>>& grid,vector<vector<int>> &memo,int x,int y,int k,int m,int n,int count) { if(x==m-1&&y==n-1 &&k>=0) { res=min(res,count); return; } if(k<0) return; //如何剪枝呢? if(grid[x][y]==1 && k==0) return; //当前格子做一个标注表示走过了 memo[x][y]=1; for(int i=0;i<4;++i) { int x_next=x+direction[i][0]; int y_next=y+direction[i][1]; if(inAera(x_next,y_next,m,n) && k>=0 &&memo[x_next][y_next]==0){ dfs(grid,memo,x_next,y_next,k-grid[x][y],m,n,count+1); } } memo[x][y]=0;//回溯 return; } };
利用队列实现广度优先:
class Solution { public: int direction[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int res=INT_MAX; int shortestPath(vector<vector<int>>& grid, int k) { int m=grid.size(),n=grid[0].size(); vector<vector<int>> memo(m,vector<int>(n,-1));//为啥是-1呢? //利用队列实现bfs if(k>=m+n-2) return m+n-2; //步数有富裕 queue<tuple<int,int,int>>ss; memo[0][0]=k; ss.push({0,0,k}); int level=0; while(!ss.empty()){ auto sz=ss.size(); ++level; while(sz--){ //广度优先 auto[x,y,ck]=ss.front(); ss.pop(); for(int i=0;i<4;++i){ int x_next=x+direction[i][0]; int y_next=y+direction[i][1]; if(inAera(x_next,y_next,m,n)){ int nk=ck-grid[x_next][y_next]; if(nk<0) continue; if(memo[x_next][y_next]>=nk) continue;//不是最短的 if(x_next==m-1 && y_next==n-1) { return level; } memo[x_next][y_next]=nk; ss.push({x_next,y_next,nk}); } } } } return -1; } bool inAera(int x,int y,int m,int n){ //judge aera return x>=0 &&x<m &&y>=0 &&y<n; } };