介绍本篇之前,我想先用人话叙述一般解决动态规划问题的思路:
动态规划的问题,本身有许多产生结果的可能,需要在具体题目下得到满足某个条件的解。
如何得到呢?
我们就需要根据这个具体问题,建立一个状态表(dp 表),在这张 dp 表中的每一个位置的数据都有明确的、相同的定义,称为 状态表示,而储存的每个数据,就是由原问题产生的每一个子问题的解。
子问题的解又该怎么得到呢?
这就需要通过对子问题如何推导(状态的转移过程)进行具体分析,要求是每个解都能由前一个解得到,从而得到所有的子问题的解。根据得到的解把 dp 表填满,最后就能在这张 dp 表中找到我们要的具体答案。
梳理一下:
此种情况需要注意对原数组访问的时候下标还需要多减一位
如果原数组是字符串,可以对原数组加一个虚拟位置(见题1.4),如下
str = '-' + str;
±0x3f3f3f3f
(int 最大值的一半)1. 子数组系列
分析状态时的通用方法:
给你一个整数数组 nums ,请你求出乘积为正数的最长子数组的长度。
一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。
请你返回乘积为正数的最长子数组长度。
如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。
例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。
给你一个整数数组 nums ,返回数组 nums 中所有为等差数组的子数组个数。
子数组是数组中的一个连续序列。
给定一个整数数组 arr ,返回 arr 的最大湍流子数组的长度 。
如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是湍流子数组 。
ps: 就是元素两两之间的增长情况是 ↗↘↗↘↗.... 这样
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。
请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
定义字符串 base 为一个 "abcdefghijklmnopqrstuvwxyz" 无限环绕的字符串,
所以 base 看起来是这样的:
"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....".
给你一个字符串 s ,请你统计并返回 s 中有多少 不同非空子串 也在 base 中出现。
2. 子序列系列
需要和子数组区别,子序列两个要求是:不改变原序列顺序,不要求连续取数
分析状态时的通用方法:
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而 不改变其余元素的顺序。
例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。
第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。
例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。
相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。
给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。