每日一题之重写比较器,是九月遇到的第一个Hard
题目,用PriorityQueue
实现可以事半功倍!🌟
题目链接:502.IPO
(伪)题解
- 看到利润和资本首先想到的是背包问题,然而题目给出了要求投资的项目个数,进而放弃背包转为贪心思路
- 该题特殊之处在于对资本和利润的处理,在完成项目后可以获得纯利润,同时利润也可以增加在资本中作为启动之后项目的资本(因此可以实现一个滚雪球
- 每个项目最多被选择一次(如果使用朴素数组实现的话需要记录其是否被选过,但
PriorityQueue
可以直接将选过的元素抛出,从另一方面完美符合要求
具体思路:
- 构建二元数组实现capital的排序(为了使profits能够与之对应进行维护),需要自定义
Comparator
,实现按照项目所需资本升序排列
1 | Arrays.sort(pack, new Comparator<int[]>() { |
-
该题中选取资本采用的是“滚雪球”方式,需要保证每个项目均为当前没有被启动过的项目里符合资本要求且利润最大的,可以通过PriorityQueue+自定义Comparator实现。
引用廖雪峰老师的使用PriorityQueue:
PriorityQueue
和Queue
的区别在于,它的出队顺序与元素的优先级有关,对PriorityQueue
调用remove()
或poll()
方法,返回的总是优先级最高的元素。要使用PriorityQueue
,我们就必须给每个元素定义“优先级”。在本题中,“优先级”为所有当前资本条件可以启动的项目的利润,因此利用priorityqueue可以实现每次均返回利润最大的可启动项目,且启动过的项目会退出队列,不用继续参与比较。
PriorityQueue的基本操作
add() & offer()
:都是向优先队列中插入元素,只是Queue
接口规定二者对插入失败时的处理不同,前者在插入失败时抛出异常,后者则会返回false
;element()
和peek()
:都是获取但不删除队首元素,也就是队列中权值最小的那个元素,二者唯一的区别是当方法失败时前者抛出异常,后者返回null
remove()
和poll()
:获取并删除队首元素,区别是当方法失败时前者抛出异常,后者返回null
- 重写比较器:类似于Array中的Comparator重写
1 | PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){ |
题目代码实现
1 | class Solution { |
开学前最后一更,希望开学也能保持健康的生活习惯和勤劳的更新频率(不这不是一个flag)😿