62.Unique Paths---dp

題目連接ide

題目大意:給一個m*n的方格,從左上角走到右下角,中間無任何障礙,問有多少種走法。spa

法一:DFS,超時,簡單模板深搜,無任何剪枝,結果一半的數據超時。代碼以下:code

 1     public int uniquePaths(int m, int n) {
 2         int f[][] = {{0, 1}, {1, 0}};
 3         boolean vis[][] = new boolean[m][n];
 4         return dfs(m, n, 0, 0, 0, f, vis);
 5     }
 6     public static int dfs(int m, int n, int x, int y, int cnt, int f[][], boolean vis[][]) {
 7         if(x == m - 1 && y == n - 1) {
 8             System.out.println("answer:" + cnt);
 9             cnt++;
10             return cnt;
11         }
12         for(int i = 0; i < 2; i++) {
13             int cnt_x = x + f[i][0];
14             int cnt_y = y + f[i][1];
15             if(cnt_x < m && cnt_y < n && vis[cnt_x][cnt_y] == false) {
16                 vis[cnt_x][cnt_y] = true;
17                 cnt = dfs(m, n, cnt_x, cnt_y, cnt, f, vis);
18                 vis[cnt_x][cnt_y] = false;
19             }
20         }
21         return cnt;
22     }
View Code

法二(借鑑):很簡單的dp,dp[i][j]表示當終點座標是[i,j]時,全部可能的路徑總數代碼以下(耗時1ms):blog

 1     public int uniquePaths(int m, int n) {
 2         int dp[][] = new int[m][n];
 3         //初始化
 4         //對於第一列和第一行,走的路徑數應該初始化爲1
 5         for(int i = 0; i < m; i++) {
 6             dp[i][0] = 1;
 7         }
 8         for(int i =0 ; i < n; i++) {
 9             dp[0][i] = 1;
10         }
11         //計算dp
12         //對於dp[i][j],每個座標[i,j],均可以由其左側和上側走一步而來。相似於楊輝三角
13         for(int i = 1; i < m; i++) {
14             for(int j = 1; j < n; j++) {
15                 dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
16             }
17         }
18         return dp[m - 1][n - 1];
19     }
View Code

法三(借鑑):一維dp,還不是很懂,是怎麼來的,暫且記一下。代碼以下(耗時0ms):ip

 1 public int uniquePaths(int m, int n) {
 2         int dp[] = new int[n];
 3         //初始化,dp[i]表示某一行第i列的路徑總數
 4         for(int i = 0; i < n; i++) {
 5             dp[i] = 1;
 6         }
 7         //外層循環是每一行,第1行計算了,第2行就是利用了第1行的值,因此這裏也是左+上的和獲得當前值,只是節約了空間
 8         for(int i = 1; i < m; i++) {
 9             //對於每一行,逐一斷定每一列的路徑值。
10             for(int j = 1; j < n; j++) {
11                 dp[j] += dp[j - 1];
12             }
13         }
14         //兩層循環後,獲得的最終的值就是全部路徑的結果值。
15         return dp[n - 1];
16     }
View Code

法四(借鑑):數學方法,由左上到右下,向下要走m-1步,向右要走n-1步,也就是要走C(m+n-2, m-1)或C(m+n-2, n-1)步。而C(m, n) = A(m, n)/n!,又A(m, n)=m!/(m-n)!。則C(m+n-2, m-1)=m*(m+1)*(m+2)...*(m+n-2)/1*2*3...*(n-1)。代碼以下:leetcode

1     public int uniquePaths(int m, int n) {
2         double res = 1;
3                 //計算組合數
4         for(int i = 1; i <= n - 1; i++) {
5             res = res * (m + i - 1) / i;
6         }
7         return (int)res;
8     }
View Code
相關文章
相關標籤/搜索