You are given a 0-indexed array heights of positive integers, where heights[i] represents the height of the ith building.
If a person is in building i, they can move to any other building j if and only if i < j and heights[i] < heights[j].
You are also given another array queries where queries[i] = [ai, bi]. On the ith query, Alice is in building ai while Bob is in building bi.
Return an arrayanswhereans[i]is the index of the leftmost building where Alice and Bob can meet on theithquery. If Alice and Bob cannot move to a common building on queryi, setans[i]to-1.
Example 1:
Input: heights = [6,4,8,5,2,7], queries = [[0,1],[0,3],[2,4],[3,4],[2,2]]
Output: [2,5,-1,5,2]
Explanation: In the first query, Alice and Bob can move to building 2 since heights[0] < heights[2] and heights[1] < heights[2].
In the second query, Alice and Bob can move to building 5 since heights[0] < heights[5] and heights[3] < heights[5].
In the third query, Alice cannot meet Bob since Alice cannot move to any other building.
In the fourth query, Alice and Bob can move to building 5 since heights[3] < heights[5] and heights[4] < heights[5].
In the fifth query, Alice and Bob are already in the same building.
For ans[i] != -1, It can be shown that ans[i] is the leftmost building where Alice and Bob can meet.
For ans[i] == -1, It can be shown that there is no building where Alice and Bob can meet.
Example 2:
Input: heights = [5,3,8,2,6,1,4,6], queries = [[0,7],[3,5],[5,2],[3,0],[1,6]]
Output: [7,6,-1,4,6]
Explanation: In the first query, Alice can directly move to Bob's building since heights[0] < heights[7].
In the second query, Alice and Bob can move to building 6 since heights[3] < heights[6] and heights[5] < heights[6].
In the third query, Alice cannot meet Bob since Bob cannot move to any other building.
In the fourth query, Alice and Bob can move to building 4 since heights[3] < heights[4] and heights[0] < heights[4].
In the fifth query, Alice can directly move to Bob's building since heights[1] < heights[6].
For ans[i] != -1, It can be shown that ans[i] is the leftmost building where Alice and Bob can meet.
For ans[i] == -1, It can be shown that there is no building where Alice and Bob can meet.
Constraints:
1 <= heights.length <= 5 * 104
1 <= heights[i] <= 109
1 <= queries.length <= 5 * 104
queries[i] = [ai, bi]
0 <= ai, bi <= heights.length - 1
Solutions
Solution 1: Binary Indexed Tree
Thinking
They meet at some \(j \ge \max(a,b)\) strictly taller than the shorter one (or simply at the right building when it is already taller). Scanning the suffix per query is too slow for \(n,q \le 5 \times 10^4\).
Process queries by decreasing right endpoint and insert buildings to the right of \(r\) into a Fenwick tree keyed by compressed height and storing the smallest index. A query for the smallest index taller than \(heights[l]\) is the meeting building.
Let's denote \(queries[i] = [l_i, r_i]\), where \(l_i \le r_i\). If \(l_i = r_i\) or \(heights[l_i] < heights[r_i]\), then the answer is \(r_i\). Otherwise, we need to find the smallest \(j\) among all \(j > r_i\) and \(heights[j] > heights[l_i]\).
We can sort \(queries\) in descending order of \(r_i\), and use a pointer \(j\) to point to the current index of \(heights\) being traversed.
Next, we traverse each query \(queries[i] = (l, r)\). For the current query, if \(j > r\), then we loop to insert \(heights[j]\) into the binary indexed tree. The binary indexed tree maintains the minimum index of the suffix height (after discretization). Then, we judge whether \(l = r\) or \(heights[l] < heights[r]\). If it is, then the answer to the current query is \(r\). Otherwise, we query the minimum index of \(heights[l]\) in the binary indexed tree, which is the answer to the current query.
The time complexity is \(O((n + m) \times \log n + m \times \log m)\), and the space complexity is \(O(n + m)\). Where \(n\) and \(m\) are the lengths of \(heights\) and \(queries\) respectively.