开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
[6190. 找到所有好下标]
前后缀分解模型
先进行预处理操作:
f(i) : 表示以i为终点的,单调递减的序列的最大长度
- 如果a[i-1] < a[i] :当前f(i) = 1 即:自己本身的长度
- 如果a[i-1] >= a[i] 当前f(i) = f(i-1)+1 即:以i-1为终点的单调递减的序列的最大长度 +自己本身
g(i):表示以i为起点的,单调递增的序列的最大长度
- 如果a[i+1] < a[i] :当前f(i) = 1 即:自己本身的长度
- 如果a[i+1] >= a[i] 当前g(i) = g(i+1)+1 即:以i+1为起点的,单调递增的序列的最大长度 +自己本身
当我们想判断第i个位置是否满足要求:
要判断第i个位置前k个元素是不是单调递减的,也就是判断f(i-1)是否>=k
要判断第i个位置后k个元素是不是单调递增的,也就是判断g(i+1)是否>=k
if(f[i-1] >= k && g[i+1]>=k) {//当前i是好下下标}
class Solution {
public:
vector<int> goodIndices(vector<int>& nums, int k) {
int n = nums.size();
vector<int> f(n);//表示以i为终点的,单调递减的序列的最大长度
vector<int> g(n);//表示以i为起点的,单调递增的序列的最大长度
//从前往后推f数组
for(int i = 0;i<n;i++)
{
f[i] = 1;
if(i!=0 && nums[i-1] >= nums[i])
{
f[i] = f[i-1]+1;
}
}
//从后往前推g数组
for(int i = n-1;i>=0;i--)
{
g[i] = 1;
if(i+1<n &&nums[i+1] >= nums[i])
{
g[i] = g[i+1]+1;
}
}
vector<int> ans;
//找 k <= i <n-k之间的好下标
for(int i = k;i<n-k;i++)
{
//i之前的k个元素是非递增的 :f[i-1]>=k
//i之后的k个元素是非递减的 :g[i+1]>=k
if(f[i-1]>=k && g[i+1]>=k)
ans.push_back(i);//当前i是好下标
}
return ans;
}
};
[6192. 公因子的数目]
做法:枚举1~min(a,b)的数检查即可,找出能同时被a和b整除的数
当然因为a和b的范围都在1000以内,所以也可以直接枚举1~1000,判断能不能同时被a和b整除
class Solution {
public:
int commonFactors(int a, int b) {
int count = 0;
for(int i = 1;i<=min(a,b);i++)
{
if(a%i == 0 && b%i == 0)
count++;
}
return count;
}
};
时间复杂度:O(min(a,b))