[路飞]_Leetcode 502. IPO

178 阅读3分钟

「携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

今天我们来做一下今天的leetcode上的一道困难题

题目链接在这里 502. IPO

题意

image.png

题目有些长可能需要耐心阅读一下,理解了题意之后才能有助于后面的思考。 题目给到了两个数字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中

代码实现

了解了上面的思路之后,代码实现其实就非常简单了😎。

image.png

结束语

如果有更好的分析思路,欢迎大家在评论区发表看法!⛄