There is a long table with a line of plates and candles arranged on top of it. You are given a 0-indexed string s consisting of characters '*' and '|' only, where a '*' represents a plate and a '|' represents a candle.
You are also given a 0-indexed 2D integer array queries where queries[i] = [lefti, righti] denotes the substring s[lefti...righti] (inclusive). For each query, you need to find the number of plates between candles that are in the substring. A plate is considered between candles if there is at least one candle to its left and at least one candle to its right in the substring.
s = "||**||**|*", and a query [3, 8] denotes the substring "*||**|". The number of plates between candles in this substring is 2, as each of the two plates has at least one candle in the substring to its left and right.Return an integer array answer where answer[i] is the answer to the ith query.
Example 1:
Input: s = "**|**|***|", queries = [[2,5],[5,9]] Output: [2,3] Explanation: - queries[0] has two plates between candles. - queries[1] has three plates between candles.
Example 2:
Input: s = "***|**|*****|**||**|*", queries = [[1,17],[4,5],[14,17],[5,11],[15,16]] Output: [9,0,0,0,0] Explanation: - queries[0] has nine plates between candles. - The other queries have zero plates between candles.
Constraints:
3 <= s.length <= 105s consists of '*' and '|' characters.1 <= queries.length <= 105queries[i].length == 20 <= lefti <= righti < s.lengthWhen you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method is like counting everything one-by-one to get the answer. For this problem, we examine every possible section between two points and check if it fits our needs.
Here's how the algorithm would work step-by-step:
def platesBetweenCandlesBruteForce(stringInput, queries):
results = []
for query in queries:
start = query[0]
end = query[1]
queryResult = 0
# Iterate through all possible segments within the query range
for segmentStart in range(start, end + 1):
for segmentEnd in range(segmentStart, end + 1):
# Find the leftmost candle in the segment
leftCandle = -1
for index in range(segmentStart, segmentEnd + 1):
if stringInput[index] == '|':
leftCandle = index
break
# Find the rightmost candle in the segment
rightCandle = -1
for index in range(segmentEnd, segmentStart - 1, -1):
if stringInput[index] == '|':
rightCandle = index
break
# Check if two candles were found in this segment
if leftCandle != -1 and rightCandle != -1 and leftCandle < rightCandle:
# Count the plates between the candles
plateCount = 0
for index in range(leftCandle + 1, rightCandle):
if stringInput[index] == '*':
plateCount += 1
# Add the plates between candles to running total
queryResult += plateCount
results.append(queryResult)
return resultsThe problem asks us to count the number of items between candles in specific sections of a row. The efficient solution avoids recounting items by precalculating helpful information to quickly answer each count request.
Here's how the algorithm would work step-by-step:
def plates_between_candles(s, queries):
number_of_positions = len(s)
candle_positions = []
for i in range(number_of_positions):
if s[i] == '|':
candle_positions.append(i)
nearest_left = [0] * number_of_positions
nearest_right = [0] * number_of_positions
left_candle_position = -1
for i in range(number_of_positions):
if s[i] == '|':
left_candle_position = i
nearest_left[i] = left_candle_position
right_candle_position = -1
for i in range(number_of_positions - 1, -1, -1):
if s[i] == '|':
right_candle_position = i
nearest_right[i] = right_candle_position
result = []
for start, end in queries:
# Find the bounding candles for the range
left_bounding_candle = nearest_right[start]
right_bounding_candle = nearest_left[end]
# Ensure the candles are in the correct order
if left_bounding_candle == -1 or right_bounding_candle == -1 or left_bounding_candle >= right_bounding_candle:
result.append(0)
else:
# Count the plates between the bounding candles.
count = 0
for i in range(left_bounding_candle + 1, right_bounding_candle):
if s[i] == '*':
count += 1
result.append(count)
return result| Case | How to Handle |
|---|---|
| Empty string s or empty queries array | Return an empty list if either input is empty as no calculations can be performed. |
| String s contains no candles ('|') | Return a list of zeros with the same length as queries, as there are no candles to calculate plates between. |
| String s contains only plates ('*') | Return a list of zeros with the same length as queries, as there are no candles to bound the plates. |
| A query range contains no candles | The number of plates in this case is zero, so return 0 for this specific query. |
| Large input string (close to maximum allowed size) and large number of queries | Precompute the nearest left and right candle positions to avoid repeated scans within the queries and ensure time complexity is efficient. |
| Queries with overlapping or identical ranges | Each query is independent so overlapping or identical ranges do not change the algorithm's logic, simply the same computation being repeated multiple times. |
| String starts or ends with many plates | Precompute the left and right nearest candles to handle these leading/trailing plates and include them when the query range intersects the valid candle range. |
| Integer overflow when calculating the number of plates between candles in very long strings | Use a data type that can accommodate the largest possible number of plates, such as long or long long. |