解题思路
f[i]记录0到i之间在蜡烛内的盘子的数量;
遍历字符串,过程中记录蜡烛间盘子数量,直到遇到新蜡烛再更新f数组f[i] = f[i-1] + cnt;
其余情况为f[i] = f[i-1];
在计算区间l到r之间的盘子数时,f[r]代表r之前满足要求的盘子数,f[l]代表l之前的,但要求是l到r之间,所以要多减一些l到区间内第一个蜡烛(即l右侧第一个蜡烛)之间的盘子数;
因此多遍历一遍,记录每个位置的右侧第一个蜡烛的位置right[i];
这样每次查询的答案就是f[r] - f[right[l]],(需排除right[l] >= f[r],即区间内全是盘子的情况)
代码
class Solution {
public:
vector<int> platesBetweenCandles(string s, vector<vector<int>>& queries) {
int n = s.size(), m = queries.size();
vector<int> ans(m, 0);
vector<int> f(n, 0), right(n, n - 1);
int flag = 0, cnt = 0;
if(s[0] == '|') flag = 1;
for(int i = 1; i < n; i++) {
if(flag == 0 && s[i] == '|') {
flag = 1;
}
else if(flag == 1 && s[i] == '*') {
cnt++;
}
else if(flag == 1 && s[i] == '|') {
f[i] = cnt;
cnt = 0;
}
f[i] += f[i-1];
}
for(int i = n - 2; i >= 0; i--) {
if(s[i] == '|') right[i] = i;
else right[i] = right[i+1];
}
for(int i = 0; i < m; i++) {
int l = queries[i][0], r = queries[i][1];
if(right[l] >= r) ans[i] = 0;
else ans[i] = f[r] - f[right[l]];
}
return ans;
}
};