Plates Between Candles

medium array string binary search prefix sum

Problem

Given a string s of '*' (plates) and '|' (candles) and queries [L, R], return for each query the number of plates between two candles inside s[L..R].

Inputs = "**|**|***|", queries = [[2,5],[5,9]]
Output[2, 3]
First query: 2 plates between candles at indices 2 and 5.

def plates_between_candles(s, queries):
    n = len(s)
    prefix = [0] * (n + 1)
    nxt = [n] * n
    prv = [-1] * n
    last = -1
    for i, ch in enumerate(s):
        prefix[i + 1] = prefix[i] + (1 if ch == '*' else 0)
        if ch == '|':
            last = i
        prv[i] = last
    last = n
    for i in range(n - 1, -1, -1):
        if s[i] == '|':
            last = i
        nxt[i] = last
    ans = []
    for L, R in queries:
        l = nxt[L] if L < n else n
        r = prv[R] if R >= 0 else -1
        ans.append(prefix[r + 1] - prefix[l] if l < r else 0)
    return ans
function platesBetweenCandles(s, queries) {
  const n = s.length;
  const prefix = new Array(n + 1).fill(0);
  const nxt = new Array(n).fill(n);
  const prv = new Array(n).fill(-1);
  let last = -1;
  for (let i = 0; i < n; i++) {
    prefix[i + 1] = prefix[i] + (s[i] === '*' ? 1 : 0);
    if (s[i] === '|') last = i;
    prv[i] = last;
  }
  last = n;
  for (let i = n - 1; i >= 0; i--) {
    if (s[i] === '|') last = i;
    nxt[i] = last;
  }
  return queries.map(([L, R]) => {
    const l = nxt[L], r = prv[R];
    return l < r ? prefix[r + 1] - prefix[l] : 0;
  });
}
class Solution {
    public int[] platesBetweenCandles(String s, int[][] queries) {
        int n = s.length();
        int[] prefix = new int[n + 1];
        int[] nxt = new int[n];
        int[] prv = new int[n];
        int last = -1;
        for (int i = 0; i < n; i++) {
            prefix[i + 1] = prefix[i] + (s.charAt(i) == '*' ? 1 : 0);
            if (s.charAt(i) == '|') last = i;
            prv[i] = last;
        }
        last = n;
        for (int i = n - 1; i >= 0; i--) {
            if (s.charAt(i) == '|') last = i;
            nxt[i] = last;
        }
        int[] ans = new int[queries.length];
        for (int q = 0; q < queries.length; q++) {
            int L = queries[q][0], R = queries[q][1];
            int l = nxt[L], r = prv[R];
            ans[q] = l < r ? prefix[r + 1] - prefix[l] : 0;
        }
        return ans;
    }
}
vector<int> platesBetweenCandles(string s, vector<vector<int>>& queries) {
    int n = s.size();
    vector<int> prefix(n + 1, 0), nxt(n, n), prv(n, -1);
    int last = -1;
    for (int i = 0; i < n; i++) {
        prefix[i + 1] = prefix[i] + (s[i] == '*' ? 1 : 0);
        if (s[i] == '|') last = i;
        prv[i] = last;
    }
    last = n;
    for (int i = n - 1; i >= 0; i--) {
        if (s[i] == '|') last = i;
        nxt[i] = last;
    }
    vector<int> ans;
    for (auto& q : queries) {
        int l = nxt[q[0]], r = prv[q[1]];
        ans.push_back(l < r ? prefix[r + 1] - prefix[l] : 0);
    }
    return ans;
}
Time: O(n + q) Space: O(n)