2940. Find Building Where Alice and Bob Can Meet #986
-
Topics: You are given a 0-indexed array If a person is in building You are also given another array Return an array Example 1:
Example 2:
Constraints:
Hint:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
The problem requires determining the leftmost building where Alice and Bob can meet given their starting buildings and movement rules. Each query involves finding a meeting point based on building heights. This is challenging due to the constraints on movement and the need for efficient computation. Key Points
Approach
Plan
Solution Steps
Let's implement this solution in PHP: 2940. Find Building Where Alice and Bob Can Meet <?php
/**
* @param Integer[] $heights
* @param Integer[][] $queries
* @return Integer[]
*/
function leftmostBuildingQueries($heights, $queries) {
$ans = array_fill(0, count($queries), -1);
$stack = []; // Monotonic stack
// Iterate through queries and heights simultaneously.
$heightsIndex = count($heights) - 1;
foreach ($this->getIndexedQueries($queries) as $indexedQuery) {
$queryIndex = $indexedQuery->queryIndex;
$a = $indexedQuery->a;
$b = $indexedQuery->b;
if ($a == $b || $heights[$a] < $heights[$b]) {
// 1. Alice and Bob are already in the same index (a == b) or
// 2. Alice can jump from a -> b (heights[a] < heights[b]).
$ans[$queryIndex] = $b;
} else {
// Now, a < b and heights[a] >= heights[b].
// Gradually add heights with an index > b to the monotonic stack.
while ($heightsIndex > $b) {
// heights[heightsIndex] is a better candidate.
while (!empty($stack) && $heights[end($stack)] <= $heights[$heightsIndex]) {
array_pop($stack);
}
$stack[] = $heightsIndex--;
}
// Binary search to find the smallest index j such that j > b and
// heights[j] > heights[a], ensuring heights[j] > heights[b].
$it = $this->findUpperBound($stack, $a, $heights);
if ($it !== null) {
$ans[$queryIndex] = $it;
}
}
}
return $ans;
}
/**
* @param $queries
* @return array
*/
private function getIndexedQueries($queries) {
$indexedQueries = [];
foreach ($queries as $i => $query) {
// Make sure that a <= b.
$a = min($query[0], $query[1]);
$b = max($query[0], $query[1]);
$indexedQueries[] = new IndexedQuery($i, $a, $b);
}
// Sort queries in descending order of b.
usort($indexedQueries, function ($a, $b) {
return $b->b - $a->b;
});
return $indexedQueries;
}
/**
* @param $stack
* @param $a
* @param $heights
* @return mixed|null
*/
private function findUpperBound($stack, $a, $heights) {
foreach (array_reverse($stack) as $index) {
if ($heights[$index] > $heights[$a]) {
return $index;
}
}
return null;
}
class IndexedQuery {
public $queryIndex;
public $a; // Alice's index
public $b; // Bob's index
/**
* @param $queryIndex
* @param $a
* @param $b
*/
public function __construct($queryIndex, $a, $b) {
$this->queryIndex = $queryIndex;
$this->a = $a;
$this->b = $b;
}
}
// Test the function
$heights = [6, 4, 8, 5, 2, 7];
$queries = [[0, 1], [0, 3], [2, 4], [3, 4], [2, 2]];
print_r(leftmostBuildingQueries($heights, $queries));
$heights = [5, 3, 8, 2, 6, 1, 4, 6];
$queries = [[0, 7], [3, 5], [5, 2], [3, 0], [1, 6]];
print_r(leftmostBuildingQueries($heights, $queries));
?> Explanation:
Example WalkthroughInput:
Process:
Output:
Time Complexity
Overall: Output for ExampleInput: $heights = [6, 4, 8, 5, 2, 7];
$queries = [[0, 1], [0, 3], [2, 4], [3, 4], [2, 2]]; Output: print_r(findBuilding($heights, $queries)); // [2, 5, -1, 5, 2] This approach efficiently handles large constraints by leveraging a monotonic stack and binary search. It ensures optimal query processing while maintaining correctness. |
Beta Was this translation helpful? Give feedback.
The problem requires determining the leftmost building where Alice and Bob can meet given their starting buildings and movement rules. Each query involves finding a meeting point based on building heights. This is challenging due to the constraints on movement and the need for efficient computation.
Key Points
-1
if no such building exists.Approach
Observations:
a == b
, Alice and Bob are already at the same building.heights[a] < heights[b]
, …