502. IPO
- 题目
假设 力扣(LeetCode)即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式。
给你 n 个项目。对于每个项目 i ,它都有一个纯利润 profits[i] ,和启动该项目需要的最小资本 capital[i] 。
最初,你的资本为 w 。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。
总而言之,从给定项目中选择 最多 k 个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。
答案保证在 32 位有符号整数范围内。
示例 1:
输入:k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]
输出:4
解释:
由于你的初始资本为 0,你仅可以从 0 号项目开始。
在完成后,你将获得 1 的利润,你的总资本将变为 1。
此时你可以选择开始 1 号或 2 号项目。
由于你最多可以选择两个项目,所以你需要完成 2 号项目以获得最大的资本。
因此,输出最后最大化的资本,为 0 + 1 + 3 = 4。
示例 2:
输入:k = 3, w = 0, profits = [1,2,3], capital = [0,1,2]
输出:6
-
难度:困难
-
分类:多做
-
一些心得
写这道题解的时候,我感觉到了刷题从2021年1月份到现在的确是有进步的,从之前将题解写道word中,到学习好朋友(https://blog.youkuaiyun.com/qq_40181592?spm=1001.2014.3001.5512)的好方法将题解写到博客中,其实根本上就是对题目的总结,LeetCode的题目刷一次是不够的,更要反复刷才行,所以我每到周一会把上周每日一题卡时间再刷一遍。当然刷题是不够的,其发散性的思维,和严谨地思考边界条件更是非常重要的。想要将知识能够类推下去,最重要的就是对现有的题目(训练集)进行归纳和总结(特征提取)。我的策略是先开始会刷很多题,然后不懂的看懂题解然后自己再刷,这样能够让你更快的适应于刷题的节奏,能够入门。之后还想进一步台阶,这个时候总结归纳类比就非常重要了,这个时候刷题的难度也要上升了。在刷这道题的时候,我能够知道这题的解法就是在能够承担的项目中,找利润最大的,但是却不知道改用哪些数据结构来解决这个问题。如果不能举一反三的话,那就多见点题型吧。
-
题解
这道题的题解就是一句话,找到能够承担项目中利润最大的项目。并且要知道w是不减的,所以当前能够承担的项目,之后也一定能够承担。用到了大堆,大堆为父节点比子节点大,用大堆来储存能够承担的项目,然后取最大。
-
代码如下:
public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) { int len=profits.length; int [][]nums=new int [len][2]; int index=0; //大堆 PriorityQueue<Integer> pQueue=new PriorityQueue<>((a,b)->(b-a)); for(int i=0;i<len;i++) { nums[i][0]=capital[i]; nums[i][1]=profits[i]; } //排序,可以理解为是以nums[][0]这一列进行升序排列,同时nums[][0]与nums[][1]对应的排序 Arrays.sort(nums,(a,b)->a[0]-b[0]); //因为我们需要k次,所以就行k次判断 for(int i=0;i<k;i++) { //w的值是不减的,所以前面满足w的capital后面一定也满足 while(index<len && nums[index][0]<=w) { //将所有满足的入堆,该堆为大堆,所以是降序排列 pQueue.offer(nums[index][1]); index++; } //堆不为空,则取出大堆的优先队列的头则是最大值 if(!pQueue.isEmpty()) { w+=pQueue.poll(); } //堆为空则意味着没有满足w的项目,那么w值得不到增加,下一轮也不可能有满足w的项目,则直接结束 else { break; } } return w; }
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ipo
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。