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 ...
随机推荐
- vue 路由传参 、接收参数
传参组件 一. <router-link :to='"/main/course?navName=" +item.columnName + "&id=&quo ...
- CDH集群安装配置(五)- Cloudera Manager Server
在线安装 sudo yum install cloudera-manager-daemons cloudera-manager-server 离线安装 资源下载地址 https://archive.c ...
- 3dsmax2019卸载/安装失败/如何彻底卸载清除干净3dsmax2019注册表和文件的方法
3dsmax2019提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dsmax2019失败提示3dsmax2019安装未完成,某些产品无法安装,也有时候想重新 ...
- Python中socket经ssl加密后server开多线程
前几天手撸Python socket代码,撸完之后经过ssl加密,确保数据的安全,外加server端开启多线程保证一个客户端连接有一个线程来服务客户端,走了不少的弯路,网上的信息啥的要 ...
- 我的Python升级打怪之路【七】:网络编程
Socket网络套接字 socket通常也称为"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过”套接字“向网络发出请求或者应答网络请求. socket起源于 ...
- eclipse中修改tomcat的配置,解决全局性的get提交乱码问题
在项目中如果页面提交方式为get的时候,中文会出现乱码. 为了解决乱码问题我们有两种办法. 第一种:在程序中加入get提交乱码的解决 String username = new String(user ...
- C++析构函数(转)
创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作(例如回收创建对象时消耗的各种资源),这个函数被称为析构函数. 析构函数(Destructor)也 ...
- 1.8 js基础(常用方法小结)
1.获取随机数 var rdm=function(n,m){ return parseInt(n+Math.random()*(m-n)); } 2.位数不够补0 function toDou(inu ...
- [PY3]——内置数据结构(4)——字符串格式化(format)
字符串格式化是拼接字符串的一种手段 join和+拼接字符串的方法,难以控制格式 printf style 字符串格式化 这种方法是从c语言继承过来的 # 待格式化的字符串:一个字符串存在占位符 In ...
- Full postback triggered by LinkButton inside GridView inside UpdatePanel
GridView inside of a UpdatePanel,get the button to trigger a partial postback <asp:ScriptManager ...