开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情
502. IPO
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ip…
假设 力扣(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
提示:
- 1 <= k <=
- 0 <= w <=
- n == profits.length
- n == capital.length
- 1 <= n <=
- 0 <= profits[i] <=
- 0 <= capital[i] <=
解法
思路:如果人自己去考虑如何选择,首先是根据当前的资金取所有够启动资金中收益最大的去做,做完之后,可做的项目可能会有扩充,在扩充后的项目中再取收益最大的做,直到做完限定数目的项目。
这是贪心的思想。“候选可做项目”可以用最大堆存储,每次弹出最大收益的项目。
具体思路: 根据启动资金倒序排列,把当前所有能做的项目的收益放到大根堆中,取堆顶就是可以做的项目;只要有新的可以做的项目都首先放到堆中; 直到取到了k个项目,结束遍历,返回结果;
- python
from heapq import *
class Solution:
def findMaximizedCapital(self, k: int, w: int, profits: List[int], capital: List[int]) -> int:
n = len(profits)
if w > max(capital):
return w + sum(nlargest(k, profits)) # nlargest nsmallest
curr = 0
arr = [(capital[i], profits[i]) for i in range(n)]
arr.sort(key=lambda x: x[0])
pq = []
for _ in range(k):
while curr < n and arr[curr][0] <= w:
heappush(pq, -arr[curr][1]) # -值最小堆变最大堆
curr += 1
if pq: # 非空取第一个值
w -= heappop(pq)
else:
break
return w
- c++
typedef pair<int,int> pii;
class Solution {
public:
int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {
int n = profits.size();
int curr = 0;
priority_queue<int, vector<int>, less<int>> pq; // 降序排序
vector<pii> arr;
for(int i=0; i<n; i++)
{
arr.push_back({capital[i], profits[i]});
}
sort(arr.begin(), arr.end());
for(int i=0; i<k; i++)
{
while(curr<n && arr[curr].first <= w)
{
pq.push(arr[curr].second);
curr += 1;
}
if(!pq.empty())
{
w += pq.top();
pq.pop();
}
else
{
break;
}
}
return w;
}
};
复杂度分析
-
时间复杂度:
- O(nlog n)的时间复杂度来来创建和排序项目,往堆中添加元素的时间不超过 O(nlogn)
- 每次从堆中取出最大值并更新资本的时间为O(klogn)
-
空间复杂度:,空间复杂度主要取决于创建用于排序的数组和大根堆