在实际代码中,可能某个位置的左侧或右侧是不存在蜡烛的,此时我们将对应数组的值记为 -1。当 x 为 -1 或者 y 为 -1 或者 x \geq y 时,不存在满足条件的盘子。同时注意到因为 x 位置是蜡烛,所以盘子数量也可以表示为 preSum}y - \textit{preSum}{x,这个写法可以防止 x 为 0 时数组越界。
classSolution { public: vector<int> platesBetweenCandles(string s, vector<vector<int>>& queries){ int n = s.length(); vector<int> preSum(n); for (int i = 0, sum = 0; i < n; i++) { if (s[i] == '*') { sum++; } preSum[i] = sum; } vector<int> left(n); for (int i = 0, l = -1; i < n; i++) { if (s[i] == '|') { l = i; } left[i] = l; } vector<int> right(n); for (int i = n - 1, r = -1; i >= 0; i--) { if (s[i] == '|') { r = i; } right[i] = r; } vector<int> ans; for (auto& query : queries) { int x = right[query[0]], y = left[query[1]]; ans.push_back(x == -1 || y == -1 || x >= y ? 0 : preSum[y] - preSum[x]); } return ans; } };
publicclassSolution { publicint[] PlatesBetweenCandles(string s, int[][] queries) { int n = s.Length; int[] preSum = newint[n]; for (int i = 0, sum = 0; i < n; i++) { if (s[i] == '*') { sum++; } preSum[i] = sum; } int[] left = newint[n]; for (int i = 0, l = -1; i < n; i++) { if (s[i] == '|') { l = i; } left[i] = l; } int[] right = newint[n]; for (int i = n - 1, r = -1; i >= 0; i--) { if (s[i] == '|') { r = i; } right[i] = r; } int[] ans = newint[queries.Length]; for (int i = 0; i < queries.Length; i++) { int[] query = queries[i]; int x = right[query[0]], y = left[query[1]]; ans[i] = x == -1 || y == -1 || x >= y ? 0 : preSum[y] - preSum[x]; } return ans; } }
int* platesBetweenCandles(char * s, int** queries, int queriesSize, int* queriesColSize, int* returnSize){ int n = strlen(s); int * preSum = (int *)malloc(sizeof(int) * n); memset(preSum, 0, sizeof(int) * n); for (int i = 0, sum = 0; i < n; i++) { if (s[i] == '*') { sum++; } preSum[i] = sum; } int * left = (int *)malloc(sizeof(int) * n); memset(left, 0, sizeof(int) * n); for (int i = 0, l = -1; i < n; i++) { if (s[i] == '|') { l = i; } left[i] = l; } int * right = (int *)malloc(sizeof(int) * n); memset(right, 0, sizeof(int) * n); for (int i = n - 1, r = -1; i >= 0; i--) { if (s[i] == '|') { r = i; } right[i] = r; } int * ans = (int *)malloc(sizeof(int) * queriesSize); for (int i = 0; i < queriesSize; i++) { int x = right[queries[i][0]], y = left[queries[i][1]]; ans[i] = x == -1 || y == -1 || x >= y ? 0 : preSum[y] - preSum[x]; } free(preSum); free(left); free(right); *returnSize = queriesSize; return ans; }
classSolution: defplatesBetweenCandles(self, s: str, queries: List[List[int]]) -> List[int]: n = len(s) preSum, sum = [0] * n, 0 left, l = [0] * n, -1 for i, ch inenumerate(s): if ch == '*': sum += 1 else: l = i preSum[i] = sum left[i] = l
right, r = [0] * n, -1 for i inrange(n - 1, -1, -1): if s[i] == '|': r = i right[i] = r
ans = [0] * len(queries) for i, (x, y) inenumerate(queries): x, y = right[x], left[y] if x >= 0and y >= 0and x < y: ans[i] = preSum[y] - preSum[x] return ans
funcplatesBetweenCandles(s string, queries [][]int) []int { n := len(s) preSum := make([]int, n) left := make([]int, n) sum, l := 0, -1 for i, ch := range s { if ch == '*' { sum++ } else { l = i } preSum[i] = sum left[i] = l }
right := make([]int, n) for i, r := n-1, -1; i >= 0; i-- { if s[i] == '|' { r = i } right[i] = r }
ans := make([]int, len(queries)) for i, q := range queries { x, y := right[q[0]], left[q[1]] if x >= 0 && y >= 0 && x < y { ans[i] = preSum[y] - preSum[x] } } return ans }
var platesBetweenCandles = function(s, queries) { const n = s.length; const preSum = newArray(n).fill(0); for (let i = 0, sum = 0; i < n; i++) { if (s[i] === '*') { sum++; } preSum[i] = sum; } const left = newArray(n).fill(0);; for (let i = 0, l = -1; i < n; i++) { if (s[i] === '|') { l = i; } left[i] = l; } const right = newArray(n).fill(0);; for (let i = n - 1, r = -1; i >= 0; i--) { if (s[i] === '|') { r = i; } right[i] = r; } const ans = newArray(queries.length).fill(0); for (let i = 0; i < queries.length; i++) { const query = queries[i]; const x = right[query[0]], y = left[query[1]]; ans[i] = x === -1 || y === -1 || x >= y ? 0 : preSum[y] - preSum[x]; } return ans; };
复杂度分析
时间复杂度:O(n + q),其中 n 为数组长度,q 为询问数量。我们需要 O(n) 的时间预处理。对于每一个询问,我们需要 O(1) 的时间计算答案。
空间复杂度:O(n),其中 n 为数组长度。我们需要 O(n) 的空间保存预处理的结果。注意返回值不计入空间复杂度。