一、 Longest Valid Parentheses

方法一、一维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解法:

ref1   ref2

三、 Interleaving String

 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.

四、 Maximal Square

 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的正方形;

...

ref

#2: 一堆细节易出错。题目要求的是面积,不是边长,所以最后返回的是res * res; 第一行和第一列要特殊处理,同时把它们的值都要跟res比一下并更新res。

五、 Palindrome Partitioning II

 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: 太容易忘。

六、 Maximum Product Subarray

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是类似的。  可以用滚动数组优化空间复杂度。

ref

Backpack

Backpack II

k Sum

k Sum II

Minimum Adjustment Cost

leetcode Ch2-Dynamic Programming II的更多相关文章

  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. JavaScript数据结构-15.二叉树

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. latex排版(CTeX winEdit输出“系统找不到指定的文件”的终极解决办法)

    WinEdit的菜单栏中:Options->Execution Modes 弹出的界面见下面的图: 看上图中“1”所示位置,后面3项出现了“?”号(出现“系统找不到指定的文件”的错误时,所有项后 ...

  3. To B服务想做移动化?腾讯云案例了解一下

    本文由 腾讯云助手团队 发布于 腾讯云云+社区 | 导语:腾讯云那么多资源和服务,就不能手机管理吗? 能. 当用户在使用To B服务时,往往会遇到各种各样的限制: 1.操作难度:涉及各种权限.多重验证 ...

  4. NetXray

    NetXRay是由Cinco Networks公司开发的一个用于高级分组检错的软件,功能很强大.IP地址查询工具. 硬件要求 对硬件要求低,可运行常用的windows平台. 主要功能 1.监视网络状态 ...

  5. Lineare Algebra

    Grundlegendes Wort: 矩阵列:Das Spalte von der Matrix 行列式:Die Determinante 对角矩阵:Die diagonal Matrix 逆矩阵: ...

  6. MySQL---1、介绍

    一.MySQL简介 1.MySQL简介 MySQL是一个轻量级关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.目前MySQL被广泛地应用在Internet上的中小型网站 ...

  7. photoshop cc 2014 下载安装及汉化资源及切图简要使用教程

    这是百度经验上一个pscc 2014 版本的下载安装汉化教程,亲测有效: http://jingyan.baidu.com/article/647f0115bce3847f2148a80c.html ...

  8. C# DateTime类型和sqlserver DateTime精度不同

    在最近的项目中, 有个关于时间的功能.一个请假的时间.前端选择的时候只有日期.所以比如请一天假就是选2017-8-15和2017-8-15,这样算请这一天的假.但是后台存入数据库时我不能就存2017- ...

  9. 使用auth_request模块实现nginx端鉴权控制

    使用auth_request模块实现nginx端鉴权控制 nginx-auth-request-module 该模块是nginx一个安装模块,使用配置都比较简单,只要作用是实现权限控制拦截作用.默认高 ...

  10. protobuf简单测试应用

    protobuf是google推出的一种数据交换协议,比较适合应用于底层服务交互,nodejs提供protobufjs包的实现,下面是一个简单的测试demo: 首先是.proto文件: package ...