leetcode Ch2-Dynamic Programming [2014]
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]的更多相关文章
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- [LeetCode] 53. Maximum Subarray_Easy tag: Dynamic Programming
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- [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 ...
- [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 ...
- [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 ...
- [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 ...
随机推荐
- linux curl post/put请求
案列: -X: 请求方式 --header: 请求header -d: 请求的数据 最后跟上请求的地址 curl -X PUT --header 'Content-Type: application/ ...
- Mathematica多元隐函数作图
例: ContourPlot3D[ 1/x + 1/y + 1/z == 1/10, {x, 最小值, 最大值}, {y, 最小值, 最大值}, {z, 最小值, 最大值}]
- 使用solr模拟京东搜素功能
1 项目需求 1.可以根据关键字搜索商品 2.可以根据商品的分类和价格过滤搜索结果 3.可以根据价格排序 4.可以实现基本的分页功能 2 界面效果 3 项目环境搭建 1.创建一个动态的web工程 2. ...
- 【Css】Layout布局(一)
看下图: css框模型(Box Model),也有叫做盒模型的.规定了元素框处理元素内容.内边距.边框 和 外边距 的方式. element元素,也是内容的主体: padding内边距,也右称为填充的 ...
- weblogic JDBC Connection Pools--转官方文档
http://docs.oracle.com/cd/E13222_01/wls/docs81/ConsoleHelp/jdbc_connection_pools.html#1106016 JDBC C ...
- ASP.NET Core中使用自定义路由
上一篇文章<ASP.NET Core中使用默认MVC路由>提到了如何使用默认的MVC路由配置,通过这个配置,我们就可以把请求路由到Controller和Action,通常情况下我们使用默认 ...
- php中cookie的操作
php设置和获取cookie 创建cookie setcookie('mycookie','value',time()+86400);//参数3 cookie过期时间//函数原型:int setcoo ...
- 如何通过 PHP 获取 Azure Active Directory 令牌
在调用 Azure Rest API 时,如果是属于 Azure Resource Manager 的 API,则需要使用 Azure Active Directory (Azure AD)认证获取令 ...
- 在 Azure WebApps 中运行64位 Asp.net Core 应用
作为微软下一代的开源的跨平台的开发框架, Asp.net core 正在吸引越来越多的开发者基于其构建现代 web 应用. 目前, Azure App Service 也实现了对 asp.net co ...
- javascript预编译和执行过程总结
javascript相对于其它语言来说是一种弱类型的语言,在其它如java语言中,程序的执行需要有编译的阶段,而在javascript中也有类似的“预编译阶段”(javascript的预编译是以代码块 ...