分析
对于任意一个查询 [a, b][a,b] 而言,我们需要统计所有左边和右边能够找到蜡烛的盘子数量。显然区间 [c, d][c,d] 内的盘子都是需要被统计的。
因此,我们可以对字符串 s 进行从前往后的扫描,将所有的蜡烛下标添加到数组(数组严格递增),并预处理出盘子的「前缀和」数组。
数组right标记当前节点的右侧的最近’|‘的下标,数组left标记当前节点左侧最近的’|'的下标。
class Solution {
public int[] platesBetweenCandles(String s, int[][] queries) {
int n = s.length();
char[] ch = s.toCharArray();
int[] preSum = new int[n];
for (int i = 1; i < n; i++) {
if (ch[i] == '*') {
preSum[i] = preSum[i-1] + 1;
} else {
preSum[i] = preSum[i-1];
}
}
int[] left = new int[n];
int[] right = new int[n];
int l = -1, r = -1;
for (int i = 0; i < n; i++) {
if (ch[i] == '|') {
l = i;
}
left[i] = l;
}
for (int i = n - 1; i >= 0; i--) {
if (ch[i] == '|') {
r = i;
}
right[i] = r;
}
int m = queries.length;
int[] ans = new int[m];
for (int i = 0; i < m; i++) {
int y = left[queries[i][1]];
int x = right[queries[i][0]];
ans[i] = x == -1 || y == -1 || x > y ? 0 : preSum[y] - preSum[x];
}
return ans;
}
}