题目:

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?

Above is a 3 x 7 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

代码:

class Solution {
public:
int uniquePaths(int m, int n) {
int dp[m][n];
memset(dp, , sizeof(dp));
for ( size_t i = ; i < n; ++i ) dp[][i] = ;
for ( size_t i = ; i < m; ++i ) dp[i][] = ;
for ( size_t i = ; i < m; ++i )
{
for ( size_t j = ; j < n; ++j )
{
dp[i][j] = dp[i-][j] + dp[i][j-];
}
}
return dp[m-][n-];
}
};

tips:

常规dp解法。

=====================================

上面的代码有可以改进的地方:dp[m][n]并不用这些额外空间,只需要两个长度为n的数组即可;一个保存前一行的状态,一个用于遍历当前行的状态,每次滚动更新,可以省去额外空间。沿着上述思路改进了一版代码如下:

class Solution {
public:
int uniquePaths(int m, int n) {
int curr[n], pre[n];
for ( size_t i = ; i<n; ++i ) { pre[i]=; curr[i]=; }
curr[] = ;
for ( size_t i = ; i<m; ++i )
{
for ( size_t j = ; j<n; ++j )
{
curr[j] = curr[j-] + pre[j];
pre[j] = curr[j];
}
curr[] = ;
}
return pre[n-];
}
};

这个代码空间复杂度降到了O(n),但还是可以改进。其实只用一个一维的数组dp就可以了,代码如下。

class Solution {
public:
int uniquePaths(int m, int n) {
int curr[n];
memset(curr, , sizeof(curr));
curr[] = ;
for ( size_t i = ; i < m; ++i )
{
for ( size_t j = ; j < n; ++j )
{
curr[j] = curr[j-] + curr[j];
}
}
return curr[n-];
}
};

这里用到了滚动数组的技巧。有个细节需要注意,外层dp是可以从0行开始,省去了一部分代码。

=====================================

再学一种深搜+缓存(即“备忘录”)解法。

class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int> > cache(m+,vector<int>(n+,));
return Solution::dfs(m, n, cache);
}
static int dfs( int x, int y, vector<vector<int> >& cache )
{
if ( x< || y< ) return ;
if ( x== && y== ) return ;
int left = cache[x-][y]> ? cache[x-][y] : cache[x-][y]=Solution::dfs(x-, y, cache);
int up = cache[x][y-]> ? cache[x][y-] : cache[x][y-]=Solution::dfs(x, y-, cache);
return left+up;
}
};

有点儿类似动态规划的思想:开一个cache数组保存已经深搜遍历过的中间结果,避免重复遍历。

这里有个简化代码的技巧:定义cache的时候多定义一行和一列,这样在深搜的过程中按照dfs中的代码可以省去判断cache下标是否越界的逻辑。

===============================================

第二次过这道题,直接写了一个dp的做法。

class Solution {
public:
int uniquePaths(int m, int n) {
int dp[m][n];
fill_n(&dp[][], m*n, );
for ( int i=; i<n; ++i ) dp[][i]=;
for ( int i=; i<m; ++i ) dp[i][]=;
for ( int i=; i<m; ++i )
{
for ( int j=; j<n; ++j )
{
dp[i][j] = dp[i][j-] + dp[i-][j];
}
}
return dp[m-][n-];
}
};

【Unique Paths】cpp的更多相关文章

  1. leetcode 【 Unique Paths 】python 实现

    题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  2. 【Unique Paths II】cpp

    题目: Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. H ...

  3. leetcode 【 Unique Paths II 】 python 实现

    题目: Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. H ...

  4. 【Permutations II】cpp

    题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...

  5. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  6. Hdu 4734 【数位DP】.cpp

    题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...

  7. 【Minimum Window】cpp

    题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...

  8. 【Sudoku Solver】cpp

    题目: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated b ...

  9. 【Combination Sum 】cpp

    题目: Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C  ...

随机推荐

  1. Spring+Hibernateh使用小结

    由此我们可以看出,报出错误的地方主要是slf4j的jar包,而故障码中“Failed to load class ’org.slf4j.impl.StaticLoggerBinder‘”的意思则是“加 ...

  2. JavaScript基础:(加号,数值转换,布尔转换)

    JavaScript中加号运算符"+" 运算过程理解 1) 如果其中一个操作数是对象,则对象会遵循对象到原始值的转换规则转换为原始值.日期对象通过toString()方法执行转换, ...

  3. C++ vector常用法

    在c++中,vector是一个十分有用的容器,下面对这个容器做一下总结. 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<in ...

  4. 详细讲解:通过phpstudy 设置站点域名、站点域名管理

    我们在本地编程的时候,会遇到路径特别长的情况,这样子我们在url中的输入就会变得不方便而且容易报错,那么在phpstudy这个环境中,有一个很好的功能,就是“站点域名管理”,他能让我们的url网址大大 ...

  5. IOS UITextFieldDelegate (常用的代理方法)

    #pragma mark - UITextFieldDelegate // 返回NO代表着文本输入框不可以改变(不可以编辑) - (BOOL)textField:(UITextField *)text ...

  6. innobackupex 全备、增备脚本

    全备脚本:innobackupex --defaults-file=/etc/my.cnf --user root --password mypasswd /mydata/fullbak/ 增备脚本: ...

  7. 异常:System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms 这个实现是不是Windows平台FIPS验证的加密算法。解决方法

    遇见这个问题是在使用了MD5加密算法后报错的,可能的原因如下: 1.FIPS不兼容MD5,此时需要修改注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\C ...

  8. Aizu 2304 Reverse Roads(无向流)

    把有向图修改成无向图,并保证每条边的流量守恒并满足有向容量(即abs(flow(u,v) - flow(v,u)) <= 1)满足限制. 得到最大流,根据残流输出答案. 因为最后少了'\n'而W ...

  9. matlplotlib 为折线图填充渐变颜色

    概要   本篇记录绘图时填充颜色时的一些常用设置,主要用到了 imshow,fill 函数.   填充图实例   填充的效果图如下: 图 1:渐变色效果图 可根据下方给出的代码进行自定义. #!/us ...

  10. Oracle 分区表的索引、分区索引

    对于分区表,可以建立不分区索引.也就是说表分区,但是索引不分区.以下着重介绍分区表的分区索引. 索引与表一样,也可以分区.索引分为两类:locally partition index(局部分区索引). ...