題目地址:https://leetcode-cn.com/problems/unique-paths/
一個機器人位于一個 m x n 網(wǎng)格的左上角 (起始點在下圖中標(biāo)記為“Start” )厨埋。
機器人每次只能向下或者向右移動一步荡陷。機器人試圖達到網(wǎng)格的右下角(在下圖中標(biāo)記
為“Finish”)。
問總共有多少條不同的路徑设易?
例如蛹头,上圖是一個7 x 3 的網(wǎng)格渣蜗。有多少可能的路徑?
說明:m 和 n 的值均不超過 100
示例 1:
輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始讼昆,總共有 3 條路徑可以到達右下角骚烧。
- 向右 -> 向右 -> 向下
- 向右 -> 向下 -> 向右
- 向下 -> 向右 -> 向右
示例 2:
輸入: m = 7, n = 3
輸出: 28
編程思路
此題用到兩個技巧:
-
動態(tài)規(guī)劃
為什么使用動態(tài)規(guī)劃?因為從左上角(起點)到達每一個地點的不同路徑數(shù)目既峡,都可以通過與其鄰接的地點的路徑數(shù)目累加獲得碧查。如下圖,計算右下角地點的路徑數(shù)目可以通過其前序地點的路徑數(shù)相加而來传惠。
-
圖的廣度優(yōu)先遍歷
機器人行走的路徑點卦方,可以抽象成有向圖腐螟,從起點節(jié)點出發(fā),進行廣度優(yōu)先遍歷衬廷,即可從起點到終點逐個完成路徑數(shù)目的的計算汽绢。為什么用廣度優(yōu)先而不用深度優(yōu)先?因為深度優(yōu)先會出現(xiàn)某靠后節(jié)點所需的前序節(jié)點尚未計算的情況跌宛,而廣度優(yōu)先不會积仗。3x2情況可以抽象成如下的圖(Graph)寂曹,來一次廣度優(yōu)先遍歷,最后一個節(jié)點遍歷完成后便得到了答案漱挚。(畫中數(shù)值的含義是從起點到該節(jié)點的不同路徑的數(shù)量)
代碼
#include <iostream>
#include <queue>
using namespace std;
class Solution {
public:
int uniquePaths(int m, int n) {//m :width,n :height
//two queues for BFS
queue<int> x;
queue<int> y;
//two var for queue operation
int tmpX;
int tmpY;
int **pathAmount;//store his known path amount
bool **nodePushed;//store visit state
pathAmount=new int*[n];
nodePushed=new bool*[n];
for(int tmp=0;tmp<n;tmp++){
pathAmount[tmp]=new int[m];
nodePushed[tmp]=new bool[m];
for(int inner=0;inner<m;inner++){
pathAmount[tmp][inner]=0;
nodePushed[tmp][inner]=false;
}
}
pathAmount[0][0]=1;
//start position in
x.push(0);
y.push(0);
nodePushed[0][0]=true;
//BFS
while(x.size()>0){
//queue head out
tmpX=x.front();
x.pop();
tmpY=y.front();
y.pop();
if((tmpX+1)<m){//non m boader
pathAmount[tmpY][tmpX+1]+=pathAmount[tmpY][tmpX];//update path amount of the next
if(!nodePushed[tmpY][tmpX+1]){//push into queue if not visited
x.push(tmpX+1);
y.push(tmpY);
nodePushed[tmpY][tmpX+1]=true;
}
}
if((tmpY+1)<n){//non n boader
pathAmount[tmpY+1][tmpX]+=pathAmount[tmpY][tmpX];//update path amount of the next
if(!nodePushed[tmpY+1][tmpX]){//push into queue if not visited
x.push(tmpX);
y.push(tmpY+1);
nodePushed[tmpY+1][tmpX]=true;
}
}
}
return pathAmount[n-1][m-1];
}
};
int main(){
Solution solution;
printf("res:%d",solution.uniquePaths(21,21));
}