大根堆+贪心算法
前篇文章使用贪心算法求可达到最远建筑,还存在一些问题,只能取局部最优解。
大根堆+贪心算法
- 神偷Jacky身上带着一堆砖头和可以无限伸缩的梯子在楼顶穿梭。
- 如果遇到下一个楼顶小于等于当前楼顶,那么直接跳过去就行了
- 但如果遇到下一个楼顶大于当前楼顶爬不上去的时候,如果你是Jacky你用丢砖头还是梯子?
- 当然是丢砖头了,也许下次遇到的楼比这次高一万倍,那时候再用梯子岂不是更好!
- 丢了足够的砖头,接着往下走,直到砖头都用完了,此时该怎么操作,直接在本次用梯子吗?显然不是!
- 他从之前爬过的大楼中,找到用最多砖头的一次,此时Jacky有一个乾坤大挪移的功法,可以把那次使用砖头吸过来,
- 用一个梯子弥补砖头。 比如之前最多一次用了100个砖头,而此次使用了2个砖头,那么我们就用1个梯子换来了98块砖头,
- 可以继续前进了。
- 使用5的贪心方式,走到没梯子砖头也不够的时候,返回当前的大楼需要即可。
怎么快速找用掉最多砖头的那一次,使用堆排序
代码实现
class Solution {
public int furthestBuilding(int[] heights, int bricks, int ladders) {
PriorityQueue<Integer> hq = new PriorityQueue<>((a, b) -> b - a);
for (int i = 1; i < heights.length; i++) {
int cnt = heights[i] - heights[i - 1];
if (cnt > 0) {
hq.add(cnt);
bricks -= cnt;
if (bricks < 0) {
if (ladders > 0) {
ladders--;
bricks += hq.poll();
} else return i - 1;
}
}
}
return heights.length - 1;
}
}