"抱紧你的我,比国王富有~"
31、最长定差子序列
(1) 题目解析
从题目来看还是很容易理解的,就是找寻数组中构成差值相等的子序列。
(2) 算法原理
class Solution {
public:
int longestSubsequence(vector<int>& arr, int difference) {
// {a,dp[i]}
unordered_map<int,int> hash;
hash[arr[0]] = 1;
int ret = 0;
for(int i=1; i<arr.size(); ++i)
{
// 不存在k hash[arr[i] - difference]==0, 这里也是1
// 存在k 那么直接+1即可
hash[arr[i]] = hash[arr[i] - difference] + 1;
ret = max(ret,hash[arr[i]]);
}
return ret;
}
};
32、子序列问题_最长斐波那契子序列的长度
(1) 题目解析
(2) 算法原理
class Solution {
public:
int lenLongestFibSubseq(vector<int>& arr) {
// hash: {元素,下标}
unordered_map<int,int> hash;
for(int i=0; i<arr.size(); ++i)
{
hash[arr[i]] = i;
}
int n = arr.size();
vector<vector<int>> dp(n,vector<int>(n,2));
int ret = 2;
// 从第二个第三个开始查找
for(int i=2; i<n; ++i)
{
for(int j=1; j<i; ++j)
{
int a = arr[i]-arr[j];
// 比较
if(a<arr[j] && hash.count(a)) dp[j][i] = dp[hash[a]][j] + 1;
ret = max(ret,dp[j][i]);
}
}
return ret < 3 ? 0 : ret;
}
};
33、最长等差数列
(1) 题目解析
等差数列?这似乎和我们之前做的一个题类似。但是,那个题是给出了差值,但是这道题却没有。因此,这两道题的解法就很不一样了。
(2) 算法原理
class Solution {
public:
int longestArithSeqLength(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> dp(n,vector<int>(n,2));
unordered_map<int,int> hash;
hash[nums[0]] = 0;
int ret = 2;
for(int i=1; i<n ;++i) // 固定倒数第二个
{
for(int j=i+1; j<n;++j) // 枚举倒数第一个
{
int a = 2*nums[i] - nums[j];
if(hash.count(a)) dp[i][j] = dp[hash[a]][i] + 1;
ret = max(ret,dp[i][j]);
}
// 更新哈希 {值,下标}
hash[nums[i]] = i;
}
return ret;
}
};
34、等差数列划分Ⅱ
(1) 题目解析
(2) 算法原理
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
unordered_map<long long, vector<long long>> hash;
int n = nums.size();
for(int i=0; i<n; ++i)
{
// 存在重复的 数字 但下标不同
hash[nums[i]].push_back(i);
}
int sum = 0;
vector<vector<int>> dp(n,vector<int>(n));
for(int j=2; j<n; ++j) // 固定倒数第一个
{
for(int i=1; i<j; ++i)
{
// 测试用例会给很大的数
long long a = (long long)2 * nums[i]-nums[j];
// 判断在不在
if(hash.count(a))
{
// 提出下标
for(auto k:hash[a])
{
if(k < i) dp[i][j] += dp[k][i] + 1;
}
}
sum += dp[i][j];
}
}
return sum;
}
};
35、回文字串
(1) 题目解析
(2) 算法原理
class Solution {
public:
int countSubstrings(string s) {
int n = s.size();
vector<vector<bool>> dp(n,vector<bool>(n));
int ret = 0;
// dp[i][j] --> s[i,j];
// 填表顺序 从下往上填 从左往右
for(int i=n-1; i>=0; --i) // 下往上
{
for(int j=i; j<n; ++j) // 左往右
{
if(s[i] == s[j])
dp[i][j] = i+1 < j ? dp[i+1][j-1]:true;
if(dp[i][j])
ret++;
}
}
return ret;
}
};
本篇到此结束,感谢你的阅读。
祝你好运,向阳而生~