Problem Description
Given an array of building heights and a list of queries where each query provides two starting building indices (for Alice and Bob), determine the leftmost building index where they can meet. A person in building i can move directly to any building j if and only if i < j and heights[i] < heights[j]. Note that a person is already at their starting building, so meeting can occur without any moves. For each query, if such a meeting building exists, return its index (ensuring it is the leftmost possible), otherwise return -1.
Key Insights
- Each query [a, b] needs to find an index j (with j ≥ max(a, b)) such that: • For the person not already at j, the jump is valid (i < j and heights[i] < heights[j]). • If one of a or b equals j, that person is already there and requires no jump.
- For two distinct starting indices, let s = min(a, b) and m = max(a, b): • First, check if m itself can be a meeting point by verifying that heights[s] < heights[m] (so that the person at the smaller index can jump to m). • If not, then any valid j must be strictly later than m. In that case the jump condition for both becomes heights[j] > max(heights[a], heights[b]). Thus, we need to find, in the range (m, n), the leftmost index j that satisfies heights[j] > max(heights[a], heights[b]).
- Since there can be up to 5×10^4 queries and 5×10^4 buildings, linear scanning per query would be too slow. We thus use a segment tree (or a similar data structure) to answer “first index with value > X in a given range” in O(log n) time.
Space and Time Complexity
Time Complexity: O((n + q) · log n), where n is the number of buildings and q is the number of queries. Space Complexity: O(n) for the segment tree.
Solution
We first handle the trivial case when both starting positions are the same (return that index). For distinct positions, set s = min(a, b) and m = max(a, b). Check if building m can serve as the meeting building by verifying that the building at s can “jump” to m (i.e. heights[s] < heights[m]). If yes, m is our answer. If not, then both must jump to a later building j > m. In that case, the meeting building must have height greater than both starting heights; that is, heights[j] > max(heights[a], heights[b]). To efficiently find the leftmost such j, we build a segment tree over the heights array. The segment tree is built to allow queries that, given a range and a threshold X, returns the leftmost index in the range where heights[index] > X. Using this structure, answer the query in O(log n) time. Key data structure: • Segment Tree – built to store the maximum height in each segment. To answer a query for the first index with height > X, we first check the maximum in the range; if it is not greater than X, no candidate exists. Otherwise, we descend recursively (preferring the left child) to find the leftmost candidate. This solution uses the fact that a direct jump is allowed and that by choosing the leftmost candidate we satisfy both the movement condition and the problem’s “leftmost meeting building” requirement.