【Leetcode】3036. Number of Subarrays That Match a Pattern II
多少次,可以用KMP算法来做。,就说这段子数组满足。
题目地址:
https://leetcode.com/problems/number-of-subarrays-that-match-a-pattern-ii/description/
给定一个长 n n n数组 a a a,和一个只含 − 1 , 0 , 1 -1,0,1 −1,0,1的长 m m m数组 p p p,题目保证 n ≥ 2 , m ≥ 1 n\ge 2, m\ge 1 n≥2,m≥1。如果存在 a a a的一个长 m + 1 m+1 m+1的子数组,使得 a [ i ] < a [ i + 1 ] , a [ i ] = a [ i + 1 ] , a [ i ] > a [ i + 1 ] a[i]<a[i+1],a[i]=a[i+1],a[i]>a[i+1] a[i]<a[i+1],a[i]=a[i+1],a[i]>a[i+1]分别等价于 p [ i ] = 1 , 0 , − 1 p[i]=1,0,-1 p[i]=1,0,−1,就说这段子数组满足 p p p的模式。问 a a a有多少个子数组满足 p p p模式。
先将 a a a做一个变换,变换为 s s s数组,使得 s [ i ] = sgn ( a [ i + 1 ] − a [ i ] ) s[i]=\operatorname{sgn} (a[i+1]-a[i]) s[i]=sgn(a[i+1]−a[i]),问题转化为问 s s s中含子数组 p p p多少次,可以用KMP算法来做。代码如下:
class Solution {
public:
int countMatchingSubarrays(vector<int> &a, vector<int> &p) {
int n = a.size(), m = p.size();
if (n - 1 < m) return 0;
vector<int> s(n);
for (int i = 1; i < n; i++)
s[i] = (a[i] > a[i - 1]) - (a[i] < a[i - 1]);
p.insert(p.begin(), 0);
auto ne = [&](auto &p) {
vector<int> ne(m + 1);
for (int i = 2, j = 0; i <= m; i++) {
while (j && p[i] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j++;
ne[i] = j;
}
return ne;
}(p);
int res = 0;
for (int i = 1, j = 0; i <= n - 1; i++) {
while (j && s[i] != p[j + 1]) j = ne[j];
if (s[i] == p[j + 1]) j++;
if (j == m) {
res++;
j = ne[j];
}
}
return res;
}
};
时间复杂度 O ( n + m ) O(n+m) O(n+m),空间 O ( m ) O(m) O(m)。
更多推荐

所有评论(0)