You are given an integer array heights
representing the heights of buildings, some bricks
, and some ladders
.
You start your journey from building 0
and move to the next building by possibly using bricks or ladders.
While moving from building i
to building i+1
(0-indexed),
- If the current building's height is greater than or equal to the next building's height, you do not need a ladder or bricks.
- If the current building's height is less than the next building's height, you can either use one ladder or
(h[i+1] - h[i])
bricks.
Return the furthest building index (0-indexed) you can reach if you use the given ladders and bricks optimally.
Example 1:
Input: heights = [4,2,7,6,9,14,12], bricks = 5, ladders = 1 Output: 4 Explanation: Starting at building 0, you can follow these steps: - Go to building 1 without using ladders nor bricks since 4 >= 2. - Go to building 2 using 5 bricks. You must use either bricks or ladders because 2 < 7. - Go to building 3 without using ladders nor bricks since 7 >= 6. - Go to building 4 using your only ladder. You must use either bricks or ladders because 6 < 9. It is impossible to go beyond building 4 because you do not have any more bricks or ladders.
Example 2:
Input: heights = [4,12,2,7,3,18,20,3,19], bricks = 10, ladders = 2 Output: 7
Example 3:
Input: heights = [14,3,19,3], bricks = 17, ladders = 0 Output: 3
Constraints:
1 <= heights.length <= 105
1 <= heights[i] <= 106
0 <= bricks <= 109
0 <= ladders <= heights.length
Related Topics:
Binary Search, Heap
Firstly we only consider positive diffs, and ignore non-positive ones.
Secondly, we use brick for small diffs, and ladder for large diffs.
We can turn the original array into the diffs.
// original array
[4,2,7,6,9,14,12]
// diff array
[0,5,0,3,5,0,x]
Now the problem becomes "find the maximum index i
that sum( A[0]...A[i] ) - sum( top L elements ) <= B
.
We can use a min heap to keep track of the top L
items.
// OJ: https://leetcode.com/problems/furthest-building-you-can-reach/
// Author: github.com/lzl124631x
// Time: O(NlogL)
// Space: O(L)
class Solution {
public:
int furthestBuilding(vector<int>& A, int B, int L) {
long N = A.size(), sum = 0, sumTop = 0;
for (int i = 0; i < N - 1; ++i) { // convert to diff array
A[i] = max(0, A[i + 1] - A[i]);
}
priority_queue<int, vector<int>, greater<>> pq; // min-heap storing the top L diffs
for (int i = 0; i < N; ++i) {
sum += A[i];
sumTop += A[i];
pq.push(A[i]);
if (pq.size() > L) {
sumTop -= pq.top();
pq.pop();
}
if (sum - sumTop > B) return i;
}
return N - 1;
}
};
Or
// OJ: https://leetcode.com/problems/furthest-building-you-can-reach/
// Author: github.com/lzl124631x
// Time: O(NlogL)
// Space: O(L)
class Solution {
public:
int furthestBuilding(vector<int>& H, int B, int L) {
int N = H.size(), sum = 0; // sum is the sum of the diffs that we want to use bricks to handle
priority_queue<int, vector<int>, greater<>> pq; // min-heap, keep track of the L largest diffs
for (int i = 1; i < N; ++i) {
int diff = H[i] - H[i - 1]; // compute diff on the fly
if (diff <= 0) continue; // ignore negative diffs
pq.push(diff);
if (pq.size() <= L) continue; // doesn't need any brick, continue
sum += pq.top();
pq.pop();
if (sum > B) return i - 1;
}
return N - 1;
}
};