假设 力扣(LeetCode)即将开始其 IPO。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式。
给定若干个项目。对于每个项目 i,它都有一个纯利润 Pi,并且需要最小的资本 Ci 来启动相应的项目。最初,你有 W 资本。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。
总而言之,从给定项目中选择最多 k 个不同项目的列表,以最大化最终资本,并输出最终可获得的最多资本。
示例 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。
注意:
假设所有输入数字都是非负整数。
表示利润和资本的数组的长度不超过 50000。
答案保证在 32 位有符号整数范围内。
思路:
方法一:按照利润排序,然后每次从前往后遍历找到第一个可以启动的项目加入答案,直到找到了k个为止。
class Solution {
class node implements Comparable<node>{
int profit,capital;
public node(int profit,int capital) {
this.profit=profit;
this.capital=capital;
}
@Override
public int compareTo(node o) {
// TODO 自动生成的方法存根
if(profit==o.profit)
return capital-o.capital;
return o.profit-profit;
}
}
public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {
int ans=0,num=0;
int n=Profits.length;
node[] arr=new node[n];
List<node> list=new ArrayList<>();
if(n==0) return W;
for(int i=0;i<n;i++)
arr[i]=new node(Profits[i],Capital[i]);
Arrays.parallelSort(arr);
for(int i=0;i<n;i++)
list.add(arr[i]);
while(num<k) {
boolean mark=false;
for(int i=0;i<list.size();i++) {
if(list.get(i).capital<=W) {
num++;
mark=true;
W+=list.get(i).profit;
list.remove(i);
break;
}
}
if(!mark) return W;
}
return W;
}
}
方法二:大顶堆+小顶堆
我们对当前能启动的项目按照利润建立大顶堆,然后当前不能启动的项目按照所需资本建立小顶堆,然后在更新资本的过程中更新小顶堆和大顶堆即可。
class Solution {
class node implements Comparable<node>{
int profit,capital;
public node(int profit,int capital) {
this.profit=profit;
this.capital=capital;
}
@Override
public int compareTo(node o) {
// TODO 自动生成的方法存根
if(profit==o.profit)
return capital-o.capital;
return o.profit-profit;
}
}
class cmp implements Comparator<node>{
@Override
public int compare(node o1, node o2) {
// TODO 自动生成的方法存根
if(o1.capital==o2.capital)
return o2.profit-o1.profit;
return o1.capital-o2.capital;
}
}
public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {
int ans=0,num=0;
int n=Profits.length;
node[] arr=new node[n];
PriorityQueue<node>q1=new PriorityQueue<>();
PriorityQueue<node>q2=new PriorityQueue<>(new cmp());
if(n==0) return W;
for(int i=0;i<n;i++) {
if(Capital[i]<=W)
q1.add(new node(Profits[i],Capital[i]));
else
q2.add(new node(Profits[i],Capital[i]));
}
while(num<k && !q1.isEmpty()) {
node now=q1.poll();
W+=now.profit;
while(!q2.isEmpty() && q2.peek().capital<=W)
q1.add(q2.poll());
num++;
}
return W;
}
}
来源:CSDN
作者:袁珂晨
链接:https://blog.csdn.net/haut_ykc/article/details/103503263