返回
LeetCode 2055. Plates Between Candles 题解(Python)
后端
2024-01-15 03:47:01
问题
给定一个字符串 s 和一个数组 queries,字符串 s 由小写英文字母组成,queries 中的每一项 queries[i] 是一个整数数组 [left_i, right_i]。
对于每个查询 queries[i],你需要统计 s 在区间 [left_i, right_i] 中包含多少个 '|' 字符。
示例
输入:s = "**|** |**|", queries = [[2, 5], [5, 9]]
输出:[2, 3]
解释:
- 区间 [2, 5] 包含两个 '|' 字符。
- 区间 [5, 9] 包含三个 '|' 字符。
算法思路
使用向量机思想和前缀和思想解题。
- 构造一个向量机。向量机是一个一维数组,它的长度与字符串 s 的长度相同。向量机的每个元素表示对应位置字符 '|' 的数量。
- 构造前缀和数组。前缀和数组是一个一维数组,它的长度与向量机的长度相同。前缀和数组的每个元素表示从字符串 s 的开头到当前位置,向量机元素之和。
- 对于每个查询 queries[i],先计算左边界 left_i 和右边界 right_i 之间的向量机元素之和。这个值表示区间 [left_i, right_i] 中 '|' 字符的数量。然后,从这个值中减去前缀和数组中 left_i - 1 位置的元素,得到区间 [left_i, right_i] 中 '|' 字符的数量。
Python 实现
def platesBetweenCandles(s: str, queries: List[List[int]]) -> List[int]:
"""
:type s: str
:type queries: List[List[int]]
:rtype: List[int]
"""
n = len(s)
# 构造向量机
vec = [0] * n
for i in range(n):
vec[i] = 1 if s[i] == '|' else 0
# 构造前缀和数组
preSum = [0] * n
preSum[0] = vec[0]
for i in range(1, n):
preSum[i] = preSum[i - 1] + vec[i]
# 统计每个查询区间中 '|' 字符的数量
result = []
for left, right in queries:
# 计算区间 [left, right] 中 '|' 字符的数量
count = preSum[right] - (preSum[left - 1] if left > 0 else 0)
result.append(count)
return result
复杂度分析
- 时间复杂度:O(n + m),其中 n 是字符串 s 的长度,m 是查询次数。构造向量机和前缀和数组的时间复杂度是 O(n)。对于每个查询,统计区间 [left, right] 中 '|' 字符的数量的时间复杂度是 O(1)。
- 空间复杂度:O(n),其中 n 是字符串 s 的长度。向量机和前缀和数组都需要 O(n) 的空间。