leetcode 力扣 1414 网格中的最短路径题解 算法题.docx
- 文档编号:7722454
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:14
- 大小:19.42KB
leetcode 力扣 1414 网格中的最短路径题解 算法题.docx
《leetcode 力扣 1414 网格中的最短路径题解 算法题.docx》由会员分享,可在线阅读,更多相关《leetcode 力扣 1414 网格中的最短路径题解 算法题.docx(14页珍藏版)》请在冰豆网上搜索。
leetcode力扣1414网格中的最短路径题解算法题
题目:
网格中的最短路径
给你一个 m*n 的网格,其中每个单元格不是 0(空)就是 1(障碍物)。
每一步,您都可以在空白单元格中上、下、左、右移动。
如果您最多可以消除k个障碍物,请找出从左上角(0,0)到右下角(m-1,n-1)的最短路径,并返回通过该路径所需的步数。
如果找不到这样的路径,则返回-1。
示例1:
输入:
grid=
[[0,0,0],
[1,1,0],
[0,0,0],
[0,1,1],
[0,0,0]],
k=1
输出:
6
解释:
不消除任何障碍的最短路径是10。
消除位置(3,2)处的障碍后,最短路径是6。
该路径是(0,0)->(0,1)->(0,2)->(1,2)->(2,2)->(3,2)->(4,2).
示例2:
输入:
grid=
[[0,1,1],
[1,1,1],
[1,0,0]],
k=1
输出:
-1
解释:
我们至少需要消除两个障碍才能找到这样的路径。
提示:
•grid.length ==m
•grid[0].length ==n
•1<=m,n<=40
•1<=k<=m*n
•grid[i][j]==0or1
•grid[0][0]==grid[m-1][n-1]==0
语言:
C++
structNagato{
intx,y;
intrest;
Nagato(int_x,int_y,int_r):
x(_x),y(_y),rest(_r){}
};
classSolution{
private:
staticconstexprintdirs[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
public:
intshortestPath(vector
intm=grid.size(),n=grid[0].size();
if(m==1&&n==1){
return0;
}
k=min(k,m+n-3);
boolvisited[m][n][k+1];
memset(visited,false,sizeof(visited));
queue
q.emplace(0,0,k);
visited[0][0][k]=true;
for(intstep=1;q.size()>0;++step){
intcnt=q.size();
for(int_=0;_ Nagatocur=q.front(); q.pop(); for(inti=0;i<4;++i){ intnx=cur.x+dirs[i][0]; intny=cur.y+dirs[i][1]; if(nx>=0&&nx if(grid[nx][ny]==0&&! visited[nx][ny][cur.rest]){ if(nx==m-1&&ny==n-1){ returnstep; } q.emplace(nx,ny,cur.rest); visited[nx][ny][cur.rest]=true; } elseif(grid[nx][ny]==1&&cur.rest>0&&! visited[nx][ny][cur.rest-1]){ q.emplace(nx,ny,cur.rest-1); visited[nx][ny][cur.rest-1]=true; } } } } } return-1; } }; 语言: Python classSolution: defshortestPath(self,grid: List[List[int]],k: int)->int: m,n=len(grid),len(grid[0]) ifm==1andn==1: return0 k=min(k,m+n-3) visited=set([(0,0,k)]) q=collections.deque([(0,0,k)]) step=0 whilelen(q)>0: step+=1 cnt=len(q) for_inrange(cnt): x,y,rest=q.popleft() fordx,dyin[(-1,0),(1,0),(0,-1),(0,1)]: nx,ny=x+dx,y+dy if0<=nx ifgrid[nx][ny]==0and(nx,ny,rest)notinvisited: ifnx==m-1andny==n-1: returnstep q.append((nx,ny,rest)) visited.add((nx,ny,rest)) elifgrid[nx][ny]==1andrest>0and(nx,ny,rest-1)notinvisited: q.append((nx,ny,rest-1)) visited.add((nx,ny,rest-1)) return-1 语言: java classSolution{ privateint[][]dir=newint[][]{{0,1},{0,-1},{1,0},{-1,0}}; publicintshortestPath(int[][]grid,intk){ intm=grid.length; intn=grid[0].length; boolean[][][]visited=newboolean[m][n][k+1]; Queue queue.add(newPoint(0,0,0)); //**核心逻辑**: 访问记录二维扩展为三维 visited[0][0][0]=true; intdistance=0; while(! queue.isEmpty()){ distance++; intsize=queue.size(); for(inti=0;i Pointpoint=queue.poll(); intx=point.x; inty=point.y; intz=point.z; //找到障碍物 if(x==m-1&&y==n-1){ returndistance-1; } //4个方向移动 for(intj=0;j<4;j++){ intnewX=x+dir[j][0]; intnewY=y+dir[j][1]; intnewZ=z; if(newX<0||newX>=m||newY<0||newY>=n){ continue; } //**核心逻辑**: 有障碍物要对其进行处理,计算是否还能消除障碍物 if(grid[newX][newY]==1){ //没有消除k个障碍物,可以继续消除 if(z newZ=z+1; }else{ //已经消除k个障碍物 continue; } } if(! visited[newX][newY][newZ]){ queue.add(newPoint(newX,newY,newZ)); visited[newX][newY][newZ]=true; } } } } return-1; } classPoint{ intx; inty; intz; publicPoint(intx,inty,intz){ this.x=x; this.y=y; this.z=z; } } } 语言: php classSolution{ private$arr=array( array(-1,0), array(0,-1), array(1,0), array(0,1), ); /** *@paramInteger[][]$grid *@paramInteger$k *@returnInteger */ functionshortestPath($grid,$k){ if(count($grid)==1&&count($grid[0])==1){ return0; } $visited=array(); $visited['0_0_'.$k]=1; $stack=array( array(0,0,$k) ); $step=0; while(! empty($stack)){ $step++; //var_dump($step); //var_dump(count($stack)); $stack_add=array(); while(! empty($stack)){ list($i,$j,$k)=array_pop($stack); foreach($this->arras$v){ $new_i=$i+$v[0]; $new_j=$j+$v[1]; $new_k=$k; if($grid[$new_i][$new_j]==1){ $new_k--; } if($new_i<0||$new_j<0||$new_k<0 ||$new_i>count($grid)-1||$new_j>count($grid[0])-1 ||isset($visited[$new_i.'_'.$new_j.'_'.$new_k]) ){ continue; } if($new_i==count($grid)-1&&$new_j==count($grid[0])-1){ return$step; } $visited[$new_i.'_'.$new_j.'_'.$new_k]=1; $stack_add[]=array($new_i,$new_j,$new_k); } } $stack=$stack_add; } return-1; } } 语言: golang varrN,cNint funcshortestPath(grid[][]int,kint)int{ rN,cN=len(grid),len(grid[0]) ifrN==1&&cN==1{ return0 } returnbfs1(grid,k) } funcbfs1(grid[][]int,kint)int{ dir: =[][]int{{0,1},{0,-1},{1,0},{-1,0}} save: =make(map[int]map[int]int,rN*cN) fori: =0;i save[i]=make(map[int]int) } firsBlocks: =make([]int,rN*cN) queue: =make([][]int,0,rN*cN) queue=append(queue,[]int{0,0}) steps: =0 forlen(queue)>0{ preLen: =len(queue) steps++ ifsteps>rN*cN-1{ break } visit: =make([]int,rN*cN) //fmt.Println(steps,"---",queue) forj: =0;j sr,sc: =queue[0][0],queue[0][1] queue=queue[1: ] visit[sr*cN+sc]=1 fori: =0;i<4;i++{ r,c: =sr+dir[i][0],sc+dir[i][1] ifr<0||r>=rN||c<0||c>=cN{ continue } ifr==rN-1&&c==cN-1{//终点 returnsteps } idx,preIdx: =r*cN+c,sr*cN+sc blocks: =save[preIdx][steps-1]+grid[r][c] ifblocks>k{ continue } iffirsBlocks[idx]==0{ firsBlocks[blocks]=blocks }elseifblocks>firsBlocks[blocks]{ continue } if_,ok: =save[idx][steps];! ok{ save[idx][steps]=blocks }else{//同一层的扩展节点,相同 ifblocks save[idx][steps]=blocks } } ifvisit[idx]==0{ visit[idx]=1 queue=append(queue,[]int{r,c}) } } } } return-1 } 语言: golang vargridData*[][]int vardirect=[][]int{{1,0},{0,1},{-1,0},{0,-1}} varhead,tail*BfsEle varwidth,height,maxClearint varflagMapmap[int]bool//访问标记 varbestStep[40][40]int16//最优子结构记录 typeBfsElestruct{ row,col,k,stepint next*BfsEle } funcaddEle(){ for_,nowDirect: =rangedirect{ newRow: =head.row+nowDirect[0] newCol: =head.col+nowDirect[1] ifnewRow<0||newRow==height||newCol<0||newCol==width||flagMap[head.k*10000+newRow*100+newCol]{ continue } newEle: =BfsEle{newRow,newCol,-1,head.step+1,nil} if(*gridData)[newRow][newCol]==0{ newEle.k=head.k }elseifhead.k+1<=maxClear{ newEle.k=head.k+1 } ifnewEle.k! =-1&&bestStep[newRow][newCol]>int16(newEle.k){//有效则追加,无效则不动 bestStep[newRow][newCol]=int16(newEle.k) tail.next=&newEle tail=tail.next flagMap[newEle.k*10000+newRow*100+newCol]=true } } } funcshortestPath(grid[][]int,kint)int{ height=len(grid) width=len(grid[0]) gridData=&grid flagMap=make(map[int]bool) fori: =0;i forj: =0;j bestStep[i][j]=1600 } } flagMap[0]=true bestStep[0][0]=0 head=&BfsEle{0,0,0,0,nil} tail=head maxClear=k forhead! =nil{ ifhead.col==width-1&&head.row==height-1{ returnhead.step } addEle() head=head.next } return-1 } 语言: javascript varshortestPath=function(grid,k){ constdirections=[[1,0],[0,1],[-1,0],[0,-1]]; constheight=grid.length; constwidth=grid[0].length; constdp=Array(height).fill().map(_=>Array(width).fill().map(_=>Array(k+1).fill(Infinity))); dp[0][0][0]=0; constqueue=[[0,0]]; while(queue.length>0){ const[x,y]=queue.shift(); conststatus=dp[y][x]; for(const[offsetX,offsetY]ofdirections){ constnextXY=[x+offsetX,y+offsetY]; const[nextX,nextY]=nextXY; if(nextX>=0&&nextY>=0&&nextX constnextStatus=dp[nextY][nextX]; constisObstacle=grid[nextY][nextX]==1; letavailable=false; if(! isObstacle){ for(leti=0;i constnextStep=status[i]+1; if(nextStep nextStatus[i]=nextStep; available=true; } } } else{ for(leti=0;i constnextStep=status[i]+1; if(nextStep nextStatus[i+1]=nextStep; available=true; } } } if(available)queue.push(nextXY); } } } lettotalSteps=Math.min(...dp[height-1][width-1]); returntotalSteps==Infinity? -1: totalSteps; };
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- leetcode 力扣 1414 网格中的最短路径 题解 算法题 网格 中的 路径 算法