Find Building Where Alice and Bob Can Meet - Complete Solution Guide
Find Building Where Alice and Bob Can Meet is LeetCode problem 2940, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
You are given a 0-indexed array heights of positive integers, where heights[i] represents the height of the i th 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] = [a i , b i ] . On the i th query, Alice is in building a i while Bob is in building b i . Return an array ans where ans[i] is the index of the leftmost building where Alice and Bob can meet on the
Detailed Explanation
The problem asks us to find, for each query (a, b), the leftmost building index 'k' such that heights[a] < heights[k] and heights[b] < heights[k]. In other words, we need to find a meeting point 'k' to the right of both building 'a' and building 'b', where both Alice (starting at building 'a') and Bob (starting at building 'b') can move. If no such building exists, we return -1. If a and b are the same we return a, if a < b and heights[a] < heights[b], then the meeting point is b. We are given an array 'heights' representing the heights of the buildings and an array 'queries', where each query consists of a pair of building indices (a, b).
Solution Approach
The solution employs a segment tree and binary search to efficiently find the meeting point for each query. The key idea is to first handle trivial cases, then group the queries based on the maximum index of the building pair. We sort all the distinct heights and threshold heights for queries. We then iterate through the buildings in reverse order, update the segment tree with each building's index based on its height rank, and process the queries associated with each building to find the leftmost meeting point.
Step-by-Step Algorithm
- Step 1: Initialize the answer array with -1. Also, create lists to group queries according to the larger of the two indices in each query. This optimization helps processing queries efficiently.
- Step 2: Handle trivial cases: If a == b, the answer is a. If heights[min(a,b)] < heights[max(a,b)] the answer is max(a,b).
- Step 3: Store unique heights from the `heights` array and any threshold heights derived from the queries into a set. Sort this set to enable binary search later.
- Step 4: Build a segment tree. The segment tree will store the minimum index for a range of sorted height indices.
- Step 5: Iterate backwards through the buildings. This allows us to build the segment tree from right to left.
- Step 6: For each building, process any queries associated with that building. This involves binary searching to find the correct index into sorted_h for the threshold height. Then, query the segment tree to find the leftmost building index greater than this threshold height.
- Step 7: Update the segment tree with the current building's height and index. This ensures that we maintain the correct information for future queries.
- Step 8: Return the answer array.
Key Insights
- Insight 1: Sort all possible heights and the threshold heights to allow binary search, improving efficiency over iterating through all heights.
- Insight 2: Use a segment tree to efficiently find the leftmost building index that satisfies the height condition. This avoids brute-force checking of each building.
- Insight 3: Preprocess the queries by grouping them according to the taller building index. This allows us to traverse buildings in reverse order and apply the segment tree updates in the correct sequence.
Complexity Analysis
Time Complexity: O(n log n + q log n)
Space Complexity: O(n + q)
Topics
This problem involves: Array, Binary Search, Stack, Binary Indexed Tree, Segment Tree, Heap (Priority Queue), Monotonic Stack.
Companies
Asked at: Infosys.