leetcode Ch2-Dynamic Programming II
方法一、一维DP
class Solution
{
public:
int longestValidParentheses(string s)
{
vector<int> dp(s.size(),);
int res=;
for(int i=s.size()-;i>=;i--)
{
if(s[i]==')')
dp[i]=;
else
{
int j=i+dp[i+]+;
if(j<s.size()&&s[j]==')')
{
dp[i]+=dp[i+]+;
if(j+<s.size())
dp[i]+=dp[j+];
}
}
res=max(res,dp[i]);
}
return res;
}
};
像这种连续的子串,类似于最大连续子串和,在dp时往往是以某位置为结尾/起点。
dp[i]表示以s[i]为起点的最长连续括号数。下标j表示跨越了以s[i+1]为起点的一连串括号后到达的位置。如果该位置s[j]为'(' ,那说明以该'('为起点的有效括号数必然是0(否则就应该被包含进以s[i+1]为起点的有效括号串里了);而如果该位置s[j]为')',那正好和s[i]的'('匹配起来,因此s[i]可基于s[i+1]的基础上再加2,而且,除此之外还要再加上s[j+1] 。
ref1: Lexi's
#2: 忘的太快。很多细节: 判断 j < n 和 j + 1 < n。
方法二、栈
二、 Regular Expression Matching
DP解法:
class Solution
{
public:
bool isInterleave(string s1,string s2,string s3)
{
int m=s1.size(),n=s2.size();
if(m+n!=s3.size()) return false;
vector<vector<int>> f(m+,vector<int>(n+,));
f[][]=true;
for(int i=;i<=m;i++)
f[i][]=f[i-][]&&(s1[i-]==s3[i-]);
for(int i=;i<=n;i++)
f[][i]=f[][i-]&&(s2[i-]==s3[i-]);
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
f[i][j]=(s1[i-]==s3[i+j-] && f[i-][j])||(s2[j-]==s3[i+j-] && f[i][j-]);
return f[m][n];
}
};
f[i][j]表示s1从下标0开始长度为i的子串,与s2从下标0开始长度为j的子串,它们与s3从0开始长度为i+j的子串是否是interleave string。
注意这里的i,j都是长度。所以转换为下标时别忘了减1.
另外,在line8初始化时如果是以0为初始值,那就别忘了专门把f[0][0]赋值为1。
细节很多,易出错。
#2: good.
class Solution
{
public:
int maximalSquare(vector<vector<char>> &matrix)
{
if(matrix.empty()) return ;
int m=matrix.size(),n=matrix[].size();
vector<vector<int>> f(m,vector<int>(n,));
int res=;
for(int i=;i<m;i++)
{
f[i][]=matrix[i][]-'';
res=max(res,f[i][]);
}
for(int i=;i<n;i++)
{
f[][i]=matrix[][i]-'';
res=max(res,f[][i]);
}
for(int i=;i<m;i++)
{
for(int j=;j<n;j++)
{
if(matrix[i][j]=='')
{
f[i][j]=min(min(f[i-][j],f[i][j-]),f[i-][j-])+;
res=max(res,f[i][j]);
}
else f[i][j]=;
}
}
return res*res;
}
};
dp[i][j]表示以(i,j)为右下角的最大正方形的边长。那么,可得递推公式:dp[i][j]= min( dp[i-1][j] , dp[i][j-1] , dp[i-1][j-1] ) + 1;
该递推式可以先直观感受一下:
若该点周围3个点最小的dp值为0(即至少有一个点是‘0’),那最大正方形边长必然是1(即该点本身);
若该点周围3个点最小的dp值为1,那么至少这3个点都是‘1’,所以已经可以构成一个边长为2的正方形;
...
#2: 一堆细节易出错。题目要求的是面积,不是边长,所以最后返回的是res * res; 第一行和第一列要特殊处理,同时把它们的值都要跟res比一下并更新res。
class Solution
{
public:
int minCut(string s)
{
int n=s.size();
vector<int> f(n+,);
vector<vector<int>> p(n,vector<int>(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(s[i]==s[j]&&(j-i<||p[i+][j-]))
{
p[i][j]=;
f[i]=min(f[i],f[j+]+);
}
}
}
return f[];
}
};
设len=s.size(), f[i]表示从s[i]开始一直到s[len-1]这段子串的minCut数(显然,最大值即为这段子串包含的字符数减1)。
这里之所以有除了f[0]~f[len-1]之外还有个f[len]= -1,是因为后面会用到。
p[i][j]表示s[i...j]这段子串是否是回文串。判断依据就是 if ( s[i]==s[j] && (j-i<2 || p[i+1][j-1]) ) ,这个如果成立则说明s[i...j]是个回文串,那么就可以尝试更新一下 f[i]=min(f[i] , f[j+1]+1) ,即如果在j和j+1之间cut一下,那么s[i...len-1]即分成了s[i...j]和s[j+1...len-1],此时的cut数等于f[j+1]+1.
ref: soul, spring
#2: 太容易忘。
O(n) space: 【非最优】
class Solution
{
public:
int maxProduct(vector<int> &nums)
{
int n=nums.size();
vector<int> dp_max(n,);
vector<int> dp_min(n,);
int res=dp_max[]=dp_min[]=nums[];
for(int i=;i<n;i++)
{
dp_max[i]=max(nums[i],max(dp_max[i-]*nums[i],dp_min[i-]*nums[i]));
dp_min[i]=min(nums[i],min(dp_max[i-]*nums[i],dp_min[i-]*nums[i]));
res=max(res,dp_max[i]);
}
return res;
}
};
O(1) space 【最优】
class Solution
{
public:
int maxProduct(vector<int> &nums)
{
int n=nums.size();
int maxsofar,minsofar,maxpre,minpre;
int res=maxsofar=minsofar=maxpre=minpre=nums[];
for(int i=;i<n;i++)
{
maxsofar=max(nums[i],max(maxpre*nums[i],minpre*nums[i]));
minsofar=min(nums[i],min(maxpre*nums[i],minpre*nums[i]));
res=max(res,maxsofar);
maxpre=maxsofar;
minpre=minsofar;
}
return res;
}
};
#2: 细节容易出错。
七、 Decode Ways
class Solution
{
public:
int numDecodings(string s)
{
int n=s.size();
if(n==) return ;
vector<int> dp(n+,);
dp[]=;
if(s[]!='') dp[]=;
for(int i=;i<=n;i++)
{
if(s[i-]!='')
dp[i]+=dp[i-];
if(s[i-]==''||(s[i-]=='' && s[i-]<=''))
dp[i]+=dp[i-];
}
return dp[n];
}
};
dp[i]里的i表示长度,即从下标0开始的长度为i的子串的decode ways数。
要特别注意,dp[0]值为1。这是为了递推后面的值的需要。
与climb stairs是类似的。 可以用滚动数组优化空间复杂度。
Backpack
Backpack II
k Sum
k Sum II
Minimum Adjustment Cost
leetcode Ch2-Dynamic Programming II的更多相关文章
- [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 ...
随机推荐
- 【数组】Unique Paths
题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...
- maven install时报错 Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test)
今天在一个maven项目上执行maven install命令的时候一直报错,错误信息如下: [INFO] ----------------------------------------------- ...
- mix使用本地依赖
在看elixir程序设计,书中讲到依赖设置,但是都是要联网,自己希望可以下载到本地电脑硬盘,然后项目要使用就用本地的,不要每次都要下载,因为天朝下载真的不稳 官方看到文档 {:deps_name,pa ...
- Struts html(标签)
一 <html:form> <html:form>用来创建表单,<html:form>必须包含一个action属性,否则JSP会抛出一个异常. 1.常用属性: Ac ...
- [译]用R语言做挖掘数据《三》
决策树和随机森林 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到 ...
- DataGridview 绘制行序号
RowPostpaint 事件 通过Rectangle(矩形的意思)对象绘制矩形区域,然后在通过textRenderer的DeawText方法来绘制序列号. Rectangle(x,y width ...
- Hadoop学习笔记(9) ——源码初窥
Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续 ...
- JDBC的DAO设计模式
在javaEE中,java类的属性通过getter和setter来定义,get(或set)方法去除get(set)后,首字母小写即为Java类的属性.操作java类的属性有一个工具包,BeanUtil ...
- BZOJ P1059 [ZJOI2007]矩阵游戏——solution
1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4604 Solved: 2211[Submit][Stat ...
- border实现三角形的原理
前言:网上最普遍的实现三角形的方法,就是通过控制border来实现,那为什么可以呢? 原理 我们先来看看border的表现形式. #box{ width:100px; height:100px; ba ...