Unique Paths

找到不重复的能到达目标的路径数
my solution (8ms)
典型的可以用递归解决的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | class Solution { public:     int uniquePaths(int m, int n) {         _m = m;         _n = n;         _cx = 0;
          uniquePaths_do(1, 1);
          return _cx;     }
  private:     void uniquePaths_do(int m, int n) {         if (m == _m && n == _n) {             ++_cx;             return;         }
          if (m + 1 <= _m)             uniquePaths_do(m + 1, n);         if (n + 1 <= _n)             uniquePaths_do(m, n + 1);     }
      int _m;     int _n;     int _cx; };
  | 
 
结果超时了, 想了一下:
            11
     21            12
  31   22        22   13
41 32 32 23    32 23 23 14
这样子的话, 大多数的迭代都会重复
所以更改了一下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   | class Solution { public:     int uniquePaths(int m, int n) {         _m = m;         _n = n;
          return uniquePaths_do(1, 1);     }
  private:     int uniquePaths_do(int m, int n) {         auto p = make_pair(m, n);
          if (road[p] != 0) {             return road[p];         } else if (m == _m && n == _n) {             return 1;         }
          int l = 0, r = 0;         if (m + 1 <= _m)             l = uniquePaths_do(m + 1, n);         if (n + 1 <= _n)             r = uniquePaths_do(m, n + 1);
          if (road[p] == 0) {             road[p] = l + r;         }
          return l + r;     }
      int _m;     int _n;     map <pair<int, int>, int> road; };
  | 
 
通过保存的形式来去掉一些可以重用的计算, 虽然过了, 但是效果不理想

emm… 我没有再从树中能总结出什么好的规律…
the best solution
1 2 3 4 5 6 7 8 9 10 11 12
   | class Solution { public:     int uniquePaths(int m, int n) {         vector<vector<int>> path(m, vector<int>(n, 1));         for(int i = m - 2; i >= 0; i--){             for(int j = n - 2; j >= 0; j--){                 path[i][j] = path[i + 1][j] + path[i][j + 1];             }         }         return path[0][0];     } };
  | 
 
简洁又高效, 真是个漂亮的小东西
思路是这样的:
1 1 1
3 2 1
1 1 1
3 2 1
6 3 1
上述分别是 3, 2 和 3, 3 的情况, 假设 rebot 在左下角, star 在右上角(本质上不会有什么改变, 只是换了方向)
从 star 开始往后退, 每一个节点的次数都是他的 上节点次数 + 右节点次数 直到循环结束  
最后的左下角就是 rebot 的次数  
这样的算法复杂度是 O(n)