1. Triangle

 class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
int n=triangle.size();
int* res=new int[n];
for(int i=;i<n;i++)
res[i]=triangle[n-][i];
for(int i=n-;i>=;i--)
{
for(int j=;j<=i;j++)
{
res[j]=triangle[i][j]+std::min(res[j],res[j+]);
}
}
return res[];
}
};
之前用自顶向下做的,但是用自底向上会更简单些,因为 不用考虑列数是否是第一列或最后一列,行数是否是第一行,等等这一系列问题。而且最后的结果不用再通过遍历一遍最下面一行来找最小值。

2. unique paths

首先是利用了滚动数组的解法:

  class Solution {//滚动数组
public:
int uniquePaths(int m, int n) {
vector<int> dp(n,);
dp[]=;
for(int i=;i<m;i++)
{
for(int j=;j<n;j++)
{
dp[j]=dp[j-]+dp[j];
}
}
return dp[n-];
}
};

然后是普通二维dp数组的解法:

  class Solution {//二维dp数组
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m,vector<int>(n,));
for(int i=;i<m;i++)
dp[i][]=;
for(int i=;i<n;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-];
}
};

3. unique paths II

首先是使用滚动数组的解法。注意与上一题中的不同。j循环中变为从0开始,因为要确保当obstacleGrid[i][0]为0时,更新dp[j]为0.

 class Solution {//滚动数组
public:
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
if(obstacleGrid.size()==) return ;
int m=obstacleGrid.size(); int n=obstacleGrid[].size();
vector<int> dp(n,);
dp[]=;
for(int i=;i<m;i++)
{
for(int j=;j<n;j++)
{
if(obstacleGrid[i][j]==)
dp[j]=;
else if(j>)//j==0时就不执行了。
dp[j]=dp[j]+dp[j-];
}
}
return dp[n-];
}
};

使用普通二维dp数组。易错点是两层for循环都是从1开始,因为涉及到dp[j-1]。

 class Solution {//普通二维dp数组
public:
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
if(obstacleGrid.size()==) return ;
int m=obstacleGrid.size(); int n=obstacleGrid[].size();
vector<vector<int>> dp(m,vector<int>(n,));
for(int i=;i<m;i++)
{
if(obstacleGrid[i][]==) break;
else dp[i][]=;
}
for(int i=;i<n;i++)
{
if(obstacleGrid[][i]==) break;
else dp[][i]=;
}
for(int i=;i<m;i++)//注意:从1开始
{
for(int j=;j<n;j++)//注意:从1开始
{
if(obstacleGrid[i][j]==) dp[i][j]=;
else
dp[i][j]=dp[i-][j]+dp[i][j-];
}
}
return dp[m-][n-];
}
};

4. minimum path sum

如果不想判断临界条件,可以分配二维dp数组时多分配1行和1列,用dp[i][j]来表示从左上角到grid[i-1][j-1]的最小路径和。

下面的解法是判断临界条件的,未采用上述技巧。

二维dp数组:

 class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
if(grid.size()==) return ;
int m=grid.size();int n=grid[].size();
vector<vector<int>> dp(m,vector<int>(n,));
dp[][]=grid[][];
for(int i=;i<m;i++)
dp[i][]=dp[i-][]+grid[i][];
for(int i=;i<n;i++)
dp[][i]=dp[][i-]+grid[][i];
for(int i=;i<m;i++)
{
for(int j=;j<n;j++)
{
dp[i][j]=grid[i][j]+std::min(dp[i-][j],dp[i][j-]);
}
}
return dp[m-][n-];
}
};

滚动数组:

 class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
if(grid.size()==) return ;
int m=grid.size();int n=grid[].size();
vector<int> dp(n,INT_MAX);//初始值需要设成INT_MAX,因为后面有min比较。
dp[]=;
for(int i=;i<m;i++)
{
dp[]+=grid[i][];
for(int j=;j<n;j++)
{
dp[j]=grid[i][j]+std::min(dp[j],dp[j-]);
}
}
return dp[n-];
}
};

5. climbing stairs

 class Solution {
public:
int climbStairs(int n) {
if(n==||n==||n==) return n;
vector<int> dp(n+,);
dp[]=;dp[]=;dp[]=;
for(int i=;i<=n;i++)
{
dp[i]=dp[i-]+dp[i-];
}
return dp[n];
}
};

用熟了之后只用3个变量就可以,不用开辟n个元素的数组。

6. jump game

 class Solution {
public:
bool canJump(int A[], int n) {
int reach=;
for(int i=;i<=reach&&i<n;i++)
{
reach=std::max(reach,A[i]+i);
if(reach>=n-) return true;
}
return false;
}
};

通过变量reach来记录当前能达到的最远位置。

7. jump game II

 class Solution {
public:
int jump(int A[], int n) {
int start=,end=,count=;
int max=;
if(n==) return ;
while(end<n)
{
count++;
for(int i=start;i<=end;i++)
{
if(A[i]+i>=n-) return count;
if(A[i]+i>max)max=A[i]+i; //max表示下一轮while循环时能遍历到的最远的地方
}
start=end+;
end=max;
} }
};

start和end表示每一轮while循环能遍历的元素区域。每下一轮的start都是这一轮的end+1,保证了无缝衔接;每下一轮的end是这一轮中计算出的max,即(在下一轮while循环时)能遍历到的最远的地方。每个元素只被遍历一次,故复杂度为O(n)。最后能覆盖到下标为n-1的元素时所经历的while轮数即为最终答案(最少jump次数)。

想不通时就代入实例跑一下,立马就清晰了。

8. palindrome partitioning II

 class Solution {
public:
int minCut(string s) {
const int n=s.size();
vector<int> f(n+,);
vector<vector<bool>> dp(n,vector<bool>(n,));
for(int i=;i<n+;i++)
{
f[i]=n--i;
}
for(int i=n-;i>=;i--)
{
for(int j=i;j<n;j++)
{
if((i==j)||(s[i]==s[j]&&j==i+)||(s[i]==s[j]&&dp[i+][j-]))//注意判断顺序
{
dp[i][j]=;
f[i]=std::min(f[i],f[j+]+);
}
}
}
return f[];
}
};

9. word break

 class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int n=s.size();
if(n==) return ;
vector<bool> dp(n+,);
dp[]=;
for(int i=;i<=n;i++)//i表示当前长度(从下标0算起)
{
for(int k=;k<i;k++)//k表示左半子串的长度
{//通过k的变化,尝试每种分隔方式
if(dp[k]&&dict.find(s.substr(k,i-k))!=dict.end())//dp[i]表示从下标0开始的长度为i的子串是否满足word break.
{
dp[i]=;
break;
}
}
}
return dp[n];
}
};

可参考以前写的。http://www.cnblogs.com/forcheryl/p/3997304.html

10.  decode ways

 class Solution {
public:
int numDecodings(string s) {
int n=s.size();
if(n==) return ;
vector<int> dp(n+,);
dp[]=;
if(isValid(s.substr(,)))
dp[]=;
for(int i=;i<=n;i++)
{
if(isValid(s.substr(i-,)))
dp[i]+=dp[i-];
if(isValid(s.substr(i-,)))
dp[i]+=dp[i-];
}
return dp[n];
}
private:
int isValid(string s)
{
if(s[]=='') return ;
int tmp=stoi(s);
return tmp>=&&tmp<=;
}
};

关键的是先写出递推式。dp[n]=dp[n-1]*if(condition1)+dp[n-2]*if(condition2)

这里的condition1和condition2分别是判断两个对应的子串(s[i-1]、s[i-2...i-1])是否为valid。为valid时才可以累加上。

注意:dp[n]表示从下标0起的长度为n的子串的decode ways。

http://okckd.github.io/blog/2014/06/24/NineChap-Dynamic-Programming/

http://blog.csdn.net/linhuanmars/article/details/38468361

leetcode Ch2-Dynamic Programming [2014]的更多相关文章

  1. [LeetCode] 139. Word Break_ Medium tag: Dynamic Programming

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  2. [LeetCode] 45. Jump Game II_ Hard tag: Dynamic Programming

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  3. [LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  4. [LeetCode] 63. Unique Paths II_ Medium tag: Dynamic Programming

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

  5. [LeetCode] 121. Best Time to Buy and Sell Stock_Easy tag: Dynamic Programming

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  6. [LeetCode] 53. Maximum Subarray_Easy tag: Dynamic Programming

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  7. [LeetCode] 312. Burst Balloons_hard tag: 区间Dynamic Programming

    Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...

  8. [LeetCode] 64. Minimum Path Sum_Medium tag: Dynamic Programming

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  9. [LeetCode] 72. Edit Distance_hard tag: Dynamic Programming

    Given two words word1 and word2, find the minimum number of operations required to convert word1to w ...

  10. [LeetCode] 152. Maximum Product Subarray_Medium tag: Dynamic Programming

    Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...

随机推荐

  1. linux curl post/put请求

    案列: -X: 请求方式 --header: 请求header -d: 请求的数据 最后跟上请求的地址 curl -X PUT --header 'Content-Type: application/ ...

  2. Mathematica多元隐函数作图

    例: ContourPlot3D[ 1/x + 1/y + 1/z == 1/10, {x, 最小值, 最大值}, {y, 最小值, 最大值}, {z, 最小值, 最大值}]

  3. 使用solr模拟京东搜素功能

    1 项目需求 1.可以根据关键字搜索商品 2.可以根据商品的分类和价格过滤搜索结果 3.可以根据价格排序 4.可以实现基本的分页功能 2 界面效果 3 项目环境搭建 1.创建一个动态的web工程 2. ...

  4. 【Css】Layout布局(一)

    看下图: css框模型(Box Model),也有叫做盒模型的.规定了元素框处理元素内容.内边距.边框 和 外边距 的方式. element元素,也是内容的主体: padding内边距,也右称为填充的 ...

  5. weblogic JDBC Connection Pools--转官方文档

    http://docs.oracle.com/cd/E13222_01/wls/docs81/ConsoleHelp/jdbc_connection_pools.html#1106016 JDBC C ...

  6. ASP.NET Core中使用自定义路由

    上一篇文章<ASP.NET Core中使用默认MVC路由>提到了如何使用默认的MVC路由配置,通过这个配置,我们就可以把请求路由到Controller和Action,通常情况下我们使用默认 ...

  7. php中cookie的操作

    php设置和获取cookie 创建cookie setcookie('mycookie','value',time()+86400);//参数3 cookie过期时间//函数原型:int setcoo ...

  8. 如何通过 PHP 获取 Azure Active Directory 令牌

    在调用 Azure Rest API 时,如果是属于 Azure Resource Manager 的 API,则需要使用 Azure Active Directory (Azure AD)认证获取令 ...

  9. 在 Azure WebApps 中运行64位 Asp.net Core 应用

    作为微软下一代的开源的跨平台的开发框架, Asp.net core 正在吸引越来越多的开发者基于其构建现代 web 应用. 目前, Azure App Service 也实现了对 asp.net co ...

  10. javascript预编译和执行过程总结

    javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块 ...