「携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情」
今天我们来做一下今天的leetcode上的一道困难题
题目链接在这里 502. IPO
题意
题目有些长可能需要耐心阅读一下,理解了题意之后才能有助于后面的思考。 题目给到了两个数字k w,和两个数组profits capital,意思是我们现在有w的资本,可以在成本为capital[i]的利润为profits[i]的一些项目中选择k个项目,返回选择k个项目可以获得最大的利润。
而且,每次选完一个项目,这个项目的利润为a时,我们的成本就会增加a
思路
在一些项目中选择k个项目使得最终的利润最大,容易想到的是,只要我们每次选择利润最大的就好了。
但是,题目中还有一个成本的设定,我们不能选择成本高于当前资本的项目,所以,在每次选择利润最大的项目之前,我们就需要知道那些项目我们可以选,然后每次在这些可以选择的项目中选择利润最大的即可。
- 按照上面的思路,我们首先要完成的一个任务就是,当资本为w时,需要知道哪些项目可以选择。
- 一种暴力的方法就是遍历所有的项目,过滤出成本小于资本的项目即可,但是有一个问题是,一个项目选择了之后,后面就不能选了,这样的话,这个方法是不好处理的。
- 然后,我们另外一个方法就是排序,将项目的成本升序排序,并且初始化一个变量ind,表示当前选择到了那个项目,后面就从这个项目开始选择。但是,将成本排序之后,我们就没有办法根据成本获取到对应项目了,因为成本和项目的对应管理改变了,解决这个问题的办法就是,我们可以将索引进行排序,如下代码所示。
let n = profits.length; for (let i = 0; i < n; i++) ind[i] = i ind.sort((a, b) => capital[a] - capital[b]) let ind = 0; profits[ind[i]] // 获取第i个成本对应的项目利润- 我们初始化一个
ind数组代表项目成本升序后的项目下标顺序,这样我们就可以从0开始依次获取到对应的项目下标了。- 在每一轮选择中,借助到优先队列,从ind到n遍历profits数组时,将可以选择的项目都放入到优先队列中。
- 然后,选出一个利润最大的项目,作为当前选择的项目,并且更新当前资本w;如果优先队列为空,表示当前资本w时,没有项目可以选择了,此时就可以break掉了。
- 最终的输出结果保存在w中
代码实现
了解了上面的思路之后,代码实现其实就非常简单了😎。
结束语
如果有更好的分析思路,欢迎大家在评论区发表看法!⛄