"垂死坚持啊"
26、环绕字符串中唯一的子字符串
(1) 题目解析
(2) 算法原理
class Solution {
public:
int findSubstringInWraproundString(string s) {
int n = s.size();
vector<int> dp(n,1);
for(int i=1; i<n; ++i)
{
if(s[i-1]+1 ==s[i] || (s[i-1]=='z' && s[i]=='a')){
dp[i] += dp[i-1];
}
}
// 去重
int hash[26]= {0};
for(int i=0; i<n; ++i){
hash[s[i]-'a'] = max(hash[s[i]-'a'],dp[i]);
}
int sum =0;
for(auto& e:hash){
sum += e;
}
return sum;
}
};
以上就是很多关于 "子数组"类型的题型,但是我们经常看到一个概念叫做 "子序列",那么"子序列" 和 “子数组”之间有什么差别呢?它们之间有什么关系 ?
27、最长递增子序列
(1) 题目解析
(2) 算法原理
我们实质上是再套一层循环for,用来遍历(0,j)中的最长递增序列。因为dp[i]表示的是以i为结尾的,所有递增子序列最长的,(0,j)中都有可能选择比 nums[i] 更小的元素,来构成递增序列。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n =nums.size();
vector<int> dp(n,1);
int ret = 1;
for(int i=1; i<n; ++i)
{
// (0,j)的递增子序列
for(int j=0; j<i; ++j){
if(nums[j] < nums[i]){
dp[i] = max(dp[j]+1,dp[i]);
}
}
ret = max(ret,dp[i]);
}
return ret;
}
};
这是最经典的子序列问题,很多子序列题的做题模式,都会在这里找到根源。
28、摆动序列
(1) 题目解析
(2) 算法原理
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
vector<int> f(n,1);
auto g = f;
int ret = 1;
for(int i=1; i<n; ++i)
{
// (0,j)
for(int j=0; j<i; ++j){
if(nums[j] < nums[i]){
// 上升
f[i] = max(g[j]+1,f[i]);
}
else if(nums[j] > nums[i]){
g[i] = max(f[j]+1,g[i]);
}
}
ret = max(ret,max(f[i],g[i]));
}
return ret;
}
};
虽然这不是最优解,但是用动规方法来理解子序列,却是很值得肯定的地方。
29、最长递增子序列的个数
(1) 题目解析
前面是求,最长递增子序列的节点个数,现在是求 该最长子序列长度的个数。
在写在这道题之前,我们先来写一个小demo。
给你一个数组,只能只允许你遍历一次,就找出一个数组里的最大值的个数。
因此,对于这道题而言,首要做的就是先求出这个递增序列的最长长度,再来根据dp表里的值求个数。
(2) 算法原理
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int n = nums.size();
vector<int> len(n,1),count(n,1);
int retCount = 1;
int retLen = 1;
for(int i=1; i<n; ++i){
for(int j=0; j<i; ++j){
if(nums[j] < nums[i]){
if(len[j]+1 > len[i]){
len[i] = len[j] + 1;
count[i] = count[j];
}
else if(len[j]+1 == len[i]){
count[i] += count[j];
}
}
}
// 更新
if(retLen == len[i]) retCount += count[i];
else if(retLen < len[i]) retLen = len[i],retCount = count[i];
}
return retCount;
}
30、最长对数链
(1) 题目解析
(2) 算法原理
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
// 预处理
sort(pairs.begin(),pairs.end());
int n = pairs.size();
vector<int> dp(n,1);
int ret = 1;
for(int i=1; i<n; ++i){
for(int j=0; j<i; ++j){
if(pairs[j][1] < pairs[i][0]){
// 构成昌数据链
dp[i] = max(dp[j]+1,dp[i]);
}
}
ret = max(ret,dp[i]);
}
return ret;
}
};
本篇到此结束,感谢你的阅读,
祝你好运,向阳而生~