子数组问题别忘记排序这一基本操作。
做题思路
- 一维子数组(元素必须相邻的子集)问题
状态变量dp[i]:表示下标0到i的题目所求
(例如,最大子序和问题中dp[i]表示nums[0,…,i]的最大子序列和)
状态转移方程:dp[i]=f(dp[i-1],以i结尾的题目所求)
(例如最大子序问题状态转移方程为dp[i]=max(dp[i-1],sum[i]),其中sum[i]表示以i结尾的最大子序和) - 二维子数组(元素必须相邻的子集)问题
状态变量dp[i][j]:表示下标i到j的题目所求
状态转移方程:dp[i][j]=f(dp[i+1][j-1],dp[i][j-1],dp[i+1][j],元素i和元素j)
相关题目
数组
-
最大子序列积
注意max和min的运用 -
买卖股票的最佳时机
只能买卖一次 -
买卖股票的最佳时机III
最多买卖两次 -
目标和
给定一个非负整数数组和一个目标数。数组中任意一个数都只可使用+或-添加到其前面,使式子的最终结果恰好等于目标数,返回符号添加种数
例 :
输入: nums: [1, 1, 1, 1, 1], S: 3
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3 则输出5 -
连续子数组和
判断在给定数组中是否存在一个元素连续的子数组(长度>1),其总和为给定目标数的倍数。
例如[4,8,6],k=6 输出True,因为4+8=2*6
字符串
-
括号生成
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。 -
最长有效括号
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
提示:设定状态变量dp[i]表示以s[i]结尾的有效括号的长度,或是用栈 -
最长公共子序列(LCS)
i和j表示长度,因此创建的数组大小为s.size()+1,并注意初始化。
for(int i=1;i<=word1size;i++)
for(int j=1;j<=word2size;j++)
{
if(word1[i-1]==word2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
}
-
给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符
二叉树、图
-
打家劫舍III
所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。
计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。
思路:注意动态规划可以自底向上实现,也要注意自顶向下的实现(递归+哈希) -
最大正方形
注意二维DP问题是如何分类讨论的。 -
不同路径
由左上角出发,终点为右下角,求总的可行路径数量 -
不同路径II
由左上角出发,中间有障碍物,终点为右下角,求总的可行路径数量 -
出界的路径数
提示:结果数目较大因此最终结果要mod(1000000007)
数学
- 计算各个位数不同的数字个数
给定位数n,计算[0,10^n)之内各位数字均不相同的数字个数。例如n=2,输出91