IPO
Problem Descriptionβ
Problem Statement | Solution Link | LeetCode Profile |
---|---|---|
IPO | IPO Solution on LeetCode | Nikita Saini |
Problem Descriptionβ
You are given n
projects where the ith project has a pure profit profits[i]
and a minimum capital of capital[i]
is needed to start it. Initially, you have w
capital. When you finish a project, you obtain its pure profit, which is added to your total capital.
Your goal is to pick a list of at most k
distinct projects to maximize your final capital.
Constraintsβ
1 <= k <= 10^5
0 <= w <= 10^9
1 <= n <= 10^5
0 <= profits[i] <= 10^4
0 <= capital[i] <= 10^9
Approachβ
The problem can be approached using a combination of greedy strategy and efficient data structures:
- Priority Queue (Max-Heap): Use a max-heap to always select the project with the maximum profit that can be started with the current capital.
- Sorting: Sort projects based on their capital requirements.
- Iterative Selection: Iterate up to
k
times (or until no more projects can be started) to select the project with the highest profit that can be started with the current capital.
Solution in Different languagesβ
Solution in Pythonβ
import heapq
def findMaximizedCapital(k, w, profits, capital):
n = len(profits)
projects = sorted(zip(capital, profits)) # Sort projects by their capital requirements
available_projects = []
idx = 0
for _ in range(k):
while idx < n and projects[idx][0] <= w:
heapq.heappush(available_projects, -projects[idx][1]) # Max-heap for profits
idx += 1
if available_projects:
w -= heapq.heappop(available_projects) # Add the profit from the best project
else:
break
return w
# Example usage:
k = 2
w = 0
profits = [1, 2, 3]
capital = [0, 1, 1]
print(findMaximizedCapital(k, w, profits, capital)) # Output: 4
Solution in Javaβ
import java.util.PriorityQueue;
class Solution {
public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
int n = profits.length;
int[][] projects = new int[n][2];
for (int i = 0; i < n; i++) {
projects[i][0] = capital[i];
projects[i][1] = profits[i];
}
Arrays.sort(projects, (a, b) -> a[0] - b[0]); // Sort projects by their capital requirements
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
int idx = 0;
for (int i = 0; i < k; i++) {
while (idx < n && projects[idx][0] <= w) {
maxHeap.offer(projects[idx][1]); // Max-heap for profits
idx++;
}
if (!maxHeap.isEmpty()) {
w += maxHeap.poll(); // Add the profit from the best project
} else {
break;
}
}
return w;
}
}
Solution in C++β
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
class Solution {
public:
int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {
int n = profits.size();
vector<pair<int, int>> projects(n);
for (int i = 0; i < n; ++i) {
projects[i] = {capital[i], profits[i]};
}
sort(projects.begin(), projects.end()); // Sort projects by their capital requirements
priority_queue<int> maxHeap;
int idx = 0;
for (int i = 0; i < k; ++i) {
while (idx < n && projects[idx].first <= w) {
maxHeap.push(projects[idx].second); // Max-heap for profits
++idx;
}
if (!maxHeap.empty()) {
w += maxHeap.top(); // Add the profit from the best project
maxHeap.pop();
} else {
break;
}
}
return w;
}
};
Solution in Cβ
#include <stdlib.h>
// Helper function to sort projects by capital requirement
int compare(const void *a, const void *b) {
int *projA = *(int **)a;
int *projB = *(int **)b;
return projA[0] - projB[0];
}
int findMaximizedCapital(int k, int w, int* profits, int profitsSize, int* capital, int capitalSize) {
int n = profitsSize;
int **projects = (int **)malloc(n * sizeof(int *));
for (int i = 0; i < n; ++i) {
projects[i] = (int *)malloc(2 * sizeof(int));
projects[i][0] = capital[i];
projects[i][1] = profits[i];
}
qsort(projects, n, sizeof(int *), compare); // Sort projects by their capital requirements
int idx = 0;
for (int i = 0; i < k; ++i) {
while (idx < n && projects[idx][0] <= w) {
w += projects[idx][1]; // Add the profit from the best project
++idx;
}
if (idx == n) break;
}
for (int i = 0; i < n; ++i) {
free(projects[i]);
}
free(projects);
return w;
}
Solution in JavaScriptβ
class PriorityQueue {
constructor(comparator = (a, b) => a - b) {
this._heap = [];
this._comparator = comparator;
}
size() {
return this._heap.length;
}
isEmpty() {
return this.size() === 0;
}
peek() {
return this.isEmpty() ? undefined : this._heap[0];
}
push(...values) {
values.forEach(value => {
this._heap.push(value);
this._siftUp();
});
return this.size();
}
pop() {
const poppedValue = this.peek();
const bottom = this.size() - 1;
if (bottom > 0) {
this._swap(0, bottom);
}
this._heap.pop();
this._siftDown();
return poppedValue;
}
_parent(idx) {
return Math.floor((idx - 1) / 2);
}
_left(idx) {
return idx * 2 + 1;
}
_right(idx) {
return idx * 2 + 2;
}
_swap(i, j) {
[this._heap[i], this._heap[j]] = [this._heap[j], this._heap[i]];
}
_greater(i, j) {
return this._comparator(this._heap[i], this._heap[j]) < 0;
}
_siftUp() {
let node = this.size() - 1;
while (node > 0 && this._greater(node, this._parent(node))) {
this._swap(node, this._parent(node));
node = this._parent(node);
}
}
_siftDown() {
let node = 0;
while (
(this._left(node) < this.size() && this._greater(this._left(node), node)) ||
(this._right(node) < this.size() && this._greater(this._right(node), node))
) {
let maxChild = (this._right(node) < this.size() && this._greater(this._right(node), this._left(node))) ? this._right(node) : this._left(node);
this._swap(node, maxChild);
node = maxChild;
}
}
}
var findMaximizedCapital = function(k, w, profits, capital) {
const n = profits.length;
const projects = [];
for (let i = 0; i < n; i++) {
projects.push([capital[i], profits[i]]);
}
projects.sort((a, b) => a[0] - b[0]); // Sort projects by their capital requirements
const maxHeap = new PriorityQueue((a, b) => b - a);
let idx = 0;
for (let i = 0; i < k; i++) {
while (idx < n && projects[idx][0] <= w) {
maxHeap.push(projects[idx][1]); // Max-heap for profits
idx++;
}
if (!maxHeap.isEmpty()) {
w += maxHeap.pop(); // Add the profit from the best project
} else {
break;
}
}
return w;
};
Step-by-Step Algorithmβ
- Input Parsing: Convert input data into appropriate data structures (arrays, lists, or vectors).
- Sorting: Sort projects based on their capital requirements.
- Priority Queue Initialization: Initialize a max-heap (priority queue) to keep track of the most profitable projects that can be started with the current capital.
- Iterative Selection:
- For up to
k
times, iterate through the sorted projects. - Push all feasible projects (capital requirement <= current capital) into the max-heap.
- If the max-heap is not empty, pop the project with the maximum profit and add its profit to the current capital.
- Break the loop if no more projects can be started.
- For up to
- Return Result: Return the current capital after selecting up to
k
projects.
Conclusionβ
The provided solutions efficiently solve the problem of selecting at most k
projects to maximize capital using a combination of greedy strategy and priority queues. This approach ensures that the solution is optimal and runs within acceptable time limits for the given constraints.