zoukankan      html  css  js  c++  java
  • LeetCode | Unique Paths【摘】

    A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below). How many possible unique paths are there?

    最简单的回溯:

    1 int backtrack(int r, int c, int m, int n) {
    2   if (r == m && c == n)
    3     return 1;
    4   if (r > m || c > n)
    5     return 0;
    6  
    7   return backtrack(r+1, c, m, n) + backtrack(r, c+1, m, n);
    8 }

    用一个表记录状态,优化:

     1 const int M_MAX = 100;
     2 const int N_MAX = 100;
     3  
     4 int backtrack(int r, int c, int m, int n, int mat[][N_MAX+2]) {
     5   if (r == m && c == n)
     6     return 1;
     7   if (r > m || c > n)
     8     return 0;
     9  
    10   if (mat[r+1][c] == -1)
    11     mat[r+1][c] = backtrack(r+1, c, m, n, mat);
    12   if (mat[r][c+1] == -1)
    13     mat[r][c+1] = backtrack(r, c+1, m, n, mat);
    14  
    15   return mat[r+1][c] + mat[r][c+1];
    16 }
    17  
    18 int bt(int m, int n) {
    19   int mat[M_MAX+2][N_MAX+2];
    20   for (int i = 0; i < M_MAX+2; i++) {
    21     for (int j = 0; j < N_MAX+2; j++) {
    22       mat[i][j] = -1;
    23     }
    24   }
    25   return backtrack(1, 1, m, n, mat);
    26 }

    动态规划,从最靠近终点的地方(子问题)开始算:

     1 const int M_MAX = 100;
     2 const int N_MAX = 100;
     3  
     4 int dp(int m, int n) {
     5   int mat[M_MAX+2][N_MAX+2] = {0};
     6   mat[m][n+1] = 1;
     7  
     8   for (int r = m; r >= 1; r--)
     9     for (int c = n; c >= 1; c--)
    10       mat[r][c] = mat[r+1][c] + mat[r][c+1];
    11  
    12   return mat[1][1];
    13 }

    这里的空间可以进一步优化,因为最底行计算完之后可以直接用来计算上一行。

     1 class Solution {
     2 public:
     3     int uniquePaths(int m, int n) {
     4         vector<int> map(m+1, 0);
     5         map[1]=1;
     6         for(int i=0; i<n; i++){
     7             for(int j=1; j<=m; j++)
     8                 map[j] = map[j-1]+map[j];
     9         }
    10         return map[m];
    11     }
    12 }

    另外,这道题其实也是一个组合数学的题,结果就是C(m + n - 2, n - 1)。这里要注意计算是overflow。

     1 int gcd(int a, int b) {
     2     while(b) {
     3         int c = a%b;
     4         a = b;
     5         b = c;
     6     }
     7     return a;
     8 }
     9 
    10 int C(int m, int n) {
    11     if(m - n < n) {
    12         n = m - n;
    13     }
    14     int result = 1;
    15     for(int i = 1; i <= n; i++) {
    16         int mult = m;
    17         int divi = i;
    18         int g = gcd(mult,divi);
    19         mult /= g;
    20         divi /= g;
    21         result /= divi;
    22         result *= mult;
    23         m--;
    24     }
    25     return result;
    26 }

    这道题真是相当经典。

  • 相关阅读:
    unity 判断是安卓还是IOS平台
    C# set get 函数 属性访问器
    C# 字典 Dictionary
    掌握下面常用函数,学PHP不再难!
    阿里云云虚拟主机上个人网站的Https访问配置
    PHP中$_SERVER 参数详解,PHP判断当前访问的http还是https
    个人网站如何选择支付接口(API回调)
    备战NOIP——模板复习8
    备战NOIP——模板复习7
    备战NOIP——模板复习7
  • 原文地址:https://www.cnblogs.com/linyx/p/3652685.html
Copyright © 2011-2022 走看看