Skip to content

Commit 70263eb

Browse files
authored
Merge pull request #1963 from katarianikita2003/main
Create 0502-IPO.md
2 parents 96149ed + 57cd239 commit 70263eb

File tree

1 file changed

+292
-0
lines changed

1 file changed

+292
-0
lines changed
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
---
2+
id: IPO
3+
title: IPO
4+
sidebar_label: IPO
5+
tags:
6+
- Dynamic Programming
7+
- Greedy Algorithm
8+
- Priority Queue
9+
---
10+
11+
## Problem Description
12+
13+
| Problem Statement | Solution Link | LeetCode Profile |
14+
| :------------------------------------------------------ | :------------------------------------------------------------------------- | :------------------------------------------------------ |
15+
| [IPO](https://leetcode.com/problems/IPO/description/) | [IPO Solution on LeetCode](https://leetcode.com/problems/IPO/solutions/) | [Nikita Saini](https://leetcode.com/u/Saini_Nikita/) |
16+
17+
## Problem Description
18+
19+
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.
20+
21+
Your goal is to pick a list of at most `k` distinct projects to maximize your final capital.
22+
23+
## Constraints
24+
25+
- `1 <= k <= 10^5`
26+
- `0 <= w <= 10^9`
27+
- `1 <= n <= 10^5`
28+
- `0 <= profits[i] <= 10^4`
29+
- `0 <= capital[i] <= 10^9`
30+
31+
## Approach
32+
33+
The problem can be approached using a combination of greedy strategy and efficient data structures:
34+
1. **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.
35+
2. **Sorting**: Sort projects based on their capital requirements.
36+
3. **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.
37+
38+
### Solution in Different languages
39+
40+
## Solution in Python
41+
42+
```python
43+
import heapq
44+
45+
def findMaximizedCapital(k, w, profits, capital):
46+
n = len(profits)
47+
projects = sorted(zip(capital, profits)) # Sort projects by their capital requirements
48+
available_projects = []
49+
idx = 0
50+
for _ in range(k):
51+
while idx < n and projects[idx][0] <= w:
52+
heapq.heappush(available_projects, -projects[idx][1]) # Max-heap for profits
53+
idx += 1
54+
if available_projects:
55+
w -= heapq.heappop(available_projects) # Add the profit from the best project
56+
else:
57+
break
58+
return w
59+
60+
# Example usage:
61+
k = 2
62+
w = 0
63+
profits = [1, 2, 3]
64+
capital = [0, 1, 1]
65+
print(findMaximizedCapital(k, w, profits, capital)) # Output: 4
66+
```
67+
68+
## Solution in Java
69+
70+
```java
71+
import java.util.PriorityQueue;
72+
73+
class Solution {
74+
public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
75+
int n = profits.length;
76+
int[][] projects = new int[n][2];
77+
for (int i = 0; i < n; i++) {
78+
projects[i][0] = capital[i];
79+
projects[i][1] = profits[i];
80+
}
81+
Arrays.sort(projects, (a, b) -> a[0] - b[0]); // Sort projects by their capital requirements
82+
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
83+
int idx = 0;
84+
for (int i = 0; i < k; i++) {
85+
while (idx < n && projects[idx][0] <= w) {
86+
maxHeap.offer(projects[idx][1]); // Max-heap for profits
87+
idx++;
88+
}
89+
if (!maxHeap.isEmpty()) {
90+
w += maxHeap.poll(); // Add the profit from the best project
91+
} else {
92+
break;
93+
}
94+
}
95+
return w;
96+
}
97+
}
98+
```
99+
100+
## Solution in C++
101+
102+
```cpp
103+
#include <vector>
104+
#include <queue>
105+
#include <algorithm>
106+
using namespace std;
107+
108+
class Solution {
109+
public:
110+
int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {
111+
int n = profits.size();
112+
vector<pair<int, int>> projects(n);
113+
for (int i = 0; i < n; ++i) {
114+
projects[i] = {capital[i], profits[i]};
115+
}
116+
sort(projects.begin(), projects.end()); // Sort projects by their capital requirements
117+
priority_queue<int> maxHeap;
118+
int idx = 0;
119+
for (int i = 0; i < k; ++i) {
120+
while (idx < n && projects[idx].first <= w) {
121+
maxHeap.push(projects[idx].second); // Max-heap for profits
122+
++idx;
123+
}
124+
if (!maxHeap.empty()) {
125+
w += maxHeap.top(); // Add the profit from the best project
126+
maxHeap.pop();
127+
} else {
128+
break;
129+
}
130+
}
131+
return w;
132+
}
133+
};
134+
```
135+
136+
## Solution in C
137+
138+
```c
139+
#include <stdlib.h>
140+
141+
// Helper function to sort projects by capital requirement
142+
int compare(const void *a, const void *b) {
143+
int *projA = *(int **)a;
144+
int *projB = *(int **)b;
145+
return projA[0] - projB[0];
146+
}
147+
148+
int findMaximizedCapital(int k, int w, int* profits, int profitsSize, int* capital, int capitalSize) {
149+
int n = profitsSize;
150+
int **projects = (int **)malloc(n * sizeof(int *));
151+
for (int i = 0; i < n; ++i) {
152+
projects[i] = (int *)malloc(2 * sizeof(int));
153+
projects[i][0] = capital[i];
154+
projects[i][1] = profits[i];
155+
}
156+
qsort(projects, n, sizeof(int *), compare); // Sort projects by their capital requirements
157+
int idx = 0;
158+
for (int i = 0; i < k; ++i) {
159+
while (idx < n && projects[idx][0] <= w) {
160+
w += projects[idx][1]; // Add the profit from the best project
161+
++idx;
162+
}
163+
if (idx == n) break;
164+
}
165+
for (int i = 0; i < n; ++i) {
166+
free(projects[i]);
167+
}
168+
free(projects);
169+
return w;
170+
}
171+
```
172+
173+
## Solution in JavaScript
174+
175+
```javascript
176+
class PriorityQueue {
177+
constructor(comparator = (a, b) => a - b) {
178+
this._heap = [];
179+
this._comparator = comparator;
180+
}
181+
182+
size() {
183+
return this._heap.length;
184+
}
185+
186+
isEmpty() {
187+
return this.size() === 0;
188+
}
189+
190+
peek() {
191+
return this.isEmpty() ? undefined : this._heap[0];
192+
}
193+
194+
push(...values) {
195+
values.forEach(value => {
196+
this._heap.push(value);
197+
this._siftUp();
198+
});
199+
return this.size();
200+
}
201+
202+
pop() {
203+
const poppedValue = this.peek();
204+
const bottom = this.size() - 1;
205+
if (bottom > 0) {
206+
this._swap(0, bottom);
207+
}
208+
this._heap.pop();
209+
this._siftDown();
210+
return poppedValue;
211+
}
212+
213+
_parent(idx) {
214+
return Math.floor((idx - 1) / 2);
215+
}
216+
217+
_left(idx) {
218+
return idx * 2 + 1;
219+
}
220+
221+
_right(idx) {
222+
return idx * 2 + 2;
223+
}
224+
225+
_swap(i, j) {
226+
[this._heap[i], this._heap[j]] = [this._heap[j], this._heap[i]];
227+
}
228+
229+
_greater(i, j) {
230+
return this._comparator(this._heap[i], this._heap[j]) < 0;
231+
}
232+
233+
_siftUp() {
234+
let node = this.size() - 1;
235+
while (node > 0 && this._greater(node, this._parent(node))) {
236+
this._swap(node, this._parent(node));
237+
node = this._parent(node);
238+
}
239+
}
240+
241+
_siftDown() {
242+
let node = 0;
243+
while (
244+
(this._left(node) < this.size() && this._greater(this._left(node), node)) ||
245+
(this._right(node) < this.size() && this._greater(this._right(node), node))
246+
) {
247+
let maxChild = (this._right(node) < this.size() && this._greater(this._right(node), this._left(node))) ? this._right(node) : this._left(node);
248+
this._swap(node, maxChild);
249+
node = maxChild;
250+
}
251+
}
252+
}
253+
254+
var findMaximizedCapital = function(k, w, profits, capital) {
255+
const n = profits.length;
256+
const projects = [];
257+
for (let i = 0; i < n; i++) {
258+
projects.push([capital[i], profits[i]]);
259+
}
260+
projects.sort((a, b) => a[0] - b[0]); // Sort projects by their capital requirements
261+
const maxHeap = new PriorityQueue((a, b) => b - a);
262+
let idx = 0;
263+
for (let i = 0; i < k; i++) {
264+
while (idx < n && projects[idx][0] <= w) {
265+
maxHeap.push(projects[idx][1]); // Max-heap for profits
266+
idx++;
267+
}
268+
if (!maxHeap.isEmpty()) {
269+
w += maxHeap.pop(); // Add the profit from the best project
270+
} else {
271+
break;
272+
}
273+
}
274+
return w;
275+
};
276+
```
277+
278+
## Step-by-Step Algorithm
279+
280+
1. **Input Parsing**: Convert input data into appropriate data structures (arrays, lists, or vectors).
281+
2. **Sorting**: Sort projects based on their capital requirements.
282+
3. **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.
283+
4. **Iterative Selection**:
284+
- For up to `k` times, iterate through the sorted projects.
285+
- Push all feasible projects (capital requirement &lt;= current capital) into the max-heap.
286+
- If the max-heap is not empty, pop the project with the maximum profit and add its profit to the current capital.
287+
- Break the loop if no more projects can be started.
288+
5. **Return Result**: Return the current capital after selecting up to `k` projects.
289+
290+
## Conclusion
291+
292+
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.

0 commit comments

Comments
 (0)