力扣 502. IPO

题目来源:https://leetcode-cn.com/problems/ipo/

大致题意:
给定一个初始资本 w,和可以投资的项目数 k,以及项目对应的资本数组 capital 和 利润数组 profits。
返回投资可以获得的最大资本。

思路

每次项目的利润可以直接加入资本,称为新的资本值。那么肯定是想要在可以做的项目做利润最高的项目。
显然是一个贪心的过程。

堆排序 + 贪心

分析:

  • 可以做的项目,即为所需资本不大于当前资本的项目
  • 然后在可以做的项目选择利润最大的最大

解决:

  • 使用一个二维数组 cp,第一维大小即为 资本数组的大小(和利润数组大小一致),第二位大小为 2,存下对应的资本和利润。然后对数组按照资本的大小进行排序。
  • 使用一个索引,标记当前资本可以入手的项目位置,那么在当前索引位置之前的所有元素,也就是对应的项目的资本都不大于当前资本
  • 使用一个大根堆,存下可入手的项目对应的资本,只需存下资本值。
  • 遍历 k 次,每次取出堆顶的利润,加入总资本中。注意,若当前堆为空,代表没有可以入手的项目,即当前资本小于剩下的项目中所需资本的最小值,直接退出循环。

代码:

public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
        int[][] cp = new int[profits.length][2];    // 存下对应的利润和资本
        for (int i = 0; i < profits.length; i++) {
            cp[i][0] = capital[i];
            cp[i][1] = profits[i];
        }
        // 按照资本升序排序
        Arrays.sort(cp, (a, b) -> a[0] - b[0]);
        // 建立一个大根堆
        PriorityQueue<Integer> queue = new PriorityQueue<Integer>((a, b) -> b - a);
        int x = 0; // 用来记录当前数组 cp 的遍历位置
        // 进行 k 次最优选择
        // 即选择当前资本可以完成的最大项目
        for (int i = 0; i < k; i++) {
            // 若当前资本大于 cp 当前位置所需资本,入堆
            while (x < cp.length && w >= cp[x][0]) {
                queue.offer(cp[x++][1]);
            }
            // 堆不为空,证明有可以完成的项目
            if (!queue.isEmpty()) {
                w += queue.poll();
            }
            // 堆为空,没有可以入手的项目,直接退出
            else {
                break;
            }
        }
        return w;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三更鬼

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值