Skip to content

feat: update solutions to lc problems: No.1589,1705 #3882

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ requests[1] -> nums[0] + nums[1] = 3 + 5 = 8

我们观察发现,对于一次查询操作,会返回该查询区间 $[l, r]$ 中的所有元素之和。而题目要求的是所有查询操作的结果之和的最大值,也即是说,我们要累计所有查询操作的结果,使得这些结果之和最大。因此,如果一个下标 $i$ 在查询操作中出现的次数越多,那么我们就应该赋给下标 $i$ 一个较大的值,这样才能使得所有查询操作的结果之和最大。

因此,我们可以用差分数组的思想,统计每个下标在查询操作中出现的次数,然后对这些次数从小到大进行排序,然后对数组 $nums$ 也从小到大进行排序,这样就能保证每个下标 $i$ 在查询操作中出现的次数越多,该下标对应的值 $nums[i]$ 就越大。接下来,我们只需要将这些下标对应的值 $nums[i]$ 与其在查询操作中出现的次数相乘,然后累加起来,就是所有查询操作的结果之和的最大值。
因此,我们可以用差分数组的思想,统计每个下标在查询操作中出现的次数,然后对这些次数从小到大进行排序,然后对数组 $\textit{nums}$ 也从小到大进行排序,这样就能保证每个下标 $i$ 在查询操作中出现的次数越多,该下标对应的值 $\textit{nums}[i]$ 就越大。接下来,我们只需要将这些下标对应的值 $\textit{nums}[i]$ 与其在查询操作中出现的次数相乘,然后累加起来,就是所有查询操作的结果之和的最大值。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。

<!-- tabs:start -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ tags:
<pre>
<strong>Input:</strong> nums = [1,2,3,4,5], requests = [[1,3],[0,1]]
<strong>Output:</strong> 19
<strong>Explanation:</strong> One permutation of nums is [2,1,3,4,5] with the following result:
<strong>Explanation:</strong> One permutation of nums is [2,1,3,4,5] with the following result:
requests[0] -&gt; nums[1] + nums[2] + nums[3] = 1 + 3 + 4 = 8
requests[1] -&gt; nums[0] + nums[1] = 2 + 1 = 3
Total sum: 8 + 3 = 11.
Expand Down Expand Up @@ -75,7 +75,13 @@ Total sum: 11 + 8 = 19, which is the best that you can do.

<!-- solution:start -->

### Solution 1
### Solution 1: Difference Array + Sorting + Greedy

We observe that for a query operation, it returns the sum of all elements in the query interval $[l, r]$. The problem requires the maximum sum of the results of all query operations, which means we need to accumulate the results of all query operations to maximize the sum. Therefore, if an index $i$ appears more frequently in the query operations, we should assign a larger value to index $i$ to maximize the sum of the results of all query operations.

Therefore, we can use the idea of a difference array to count the number of times each index appears in the query operations, then sort these counts in ascending order, and also sort the array $\textit{nums}$ in ascending order. This ensures that the more frequently an index $i$ appears in the query operations, the larger the value $\textit{nums}[i]$ corresponding to that index will be. Next, we only need to multiply the values $\textit{nums}[i]$ corresponding to these indices by the number of times they appear in the query operations, and then sum them up to get the maximum sum of the results of all query operations.

Time complexity $O(n \times \log n)$, space complexity $O(n)$. Where $n$ is the length of the array $\textit{nums}$.

<!-- tabs:start -->

Expand Down
17 changes: 11 additions & 6 deletions solution/1700-1799/1705.Maximum Number of Eaten Apples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ tags:

因此,我们可以用优先队列(小根堆)存储苹果的腐烂时间以及对应苹果的数量,每次从优先队列中取出腐烂时间最小的苹果,然后将其数量减一,若减一后苹果的数量不为零,则将其重新放入优先队列中。若苹果已经腐烂,则从优先队列中弹出。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `apples` 或 `days` 的长度。
时间复杂度 $O(n \times \log n + M)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{days}$ 的长度,而 $M = \max(\textit{days})$

<!-- tabs:start -->

Expand Down Expand Up @@ -132,23 +132,28 @@ class Solution {
#### C++

```cpp
using pii = pair<int, int>;

class Solution {
public:
int eatenApples(vector<int>& apples, vector<int>& days) {
using pii = pair<int, int>;
priority_queue<pii, vector<pii>, greater<pii>> q;
int n = days.size();
int ans = 0, i = 0;
while (i < n || !q.empty()) {
if (i < n && apples[i]) q.emplace(i + days[i] - 1, apples[i]);
while (!q.empty() && q.top().first < i) q.pop();
if (i < n && apples[i]) {
q.emplace(i + days[i] - 1, apples[i]);
}
while (!q.empty() && q.top().first < i) {
q.pop();
}
if (!q.empty()) {
auto [t, v] = q.top();
q.pop();
--v;
++ans;
if (v && t > i) q.emplace(t, v);
if (v && t > i) {
q.emplace(t, v);
}
}
++i;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ tags:

### Solution 1: Greedy + Priority Queue

We can greedily choose the apple that is most likely to rot among the unrotten apples, so that we can eat as many apples as possible.
We can greedily choose the apples that are closest to rotting among the unrotten apples, so that we can eat as many apples as possible.

Therefore, we can use a priority queue (min heap) to store the rotting time of the apples and the corresponding number of apples. Each time we take out the apple with the smallest rotting time from the priority queue, then reduce its quantity by one. If the quantity of the apple is not zero after reduction, we put it back into the priority queue. If the apple has rotted, we pop it out from the priority queue.
Therefore, we can use a priority queue (min-heap) to store the rotting time of the apples and the corresponding number of apples. Each time, we take out the apples with the smallest rotting time from the priority queue, then decrement their quantity by one. If the quantity is not zero after decrementing, we put them back into the priority queue. If the apples have already rotted, we remove them from the priority queue.

The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array `apples` or `days`.
The time complexity is $O(n \times \log n + M)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{days}$, and $M = \max(\textit{days})$.

<!-- tabs:start -->

Expand Down Expand Up @@ -131,23 +131,28 @@ class Solution {
#### C++

```cpp
using pii = pair<int, int>;

class Solution {
public:
int eatenApples(vector<int>& apples, vector<int>& days) {
using pii = pair<int, int>;
priority_queue<pii, vector<pii>, greater<pii>> q;
int n = days.size();
int ans = 0, i = 0;
while (i < n || !q.empty()) {
if (i < n && apples[i]) q.emplace(i + days[i] - 1, apples[i]);
while (!q.empty() && q.top().first < i) q.pop();
if (i < n && apples[i]) {
q.emplace(i + days[i] - 1, apples[i]);
}
while (!q.empty() && q.top().first < i) {
q.pop();
}
if (!q.empty()) {
auto [t, v] = q.top();
q.pop();
--v;
++ans;
if (v && t > i) q.emplace(t, v);
if (v && t > i) {
q.emplace(t, v);
}
}
++i;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
using pii = pair<int, int>;

class Solution {
public:
int eatenApples(vector<int>& apples, vector<int>& days) {
using pii = pair<int, int>;
priority_queue<pii, vector<pii>, greater<pii>> q;
int n = days.size();
int ans = 0, i = 0;
while (i < n || !q.empty()) {
if (i < n && apples[i]) q.emplace(i + days[i] - 1, apples[i]);
while (!q.empty() && q.top().first < i) q.pop();
if (i < n && apples[i]) {
q.emplace(i + days[i] - 1, apples[i]);
}
while (!q.empty() && q.top().first < i) {
q.pop();
}
if (!q.empty()) {
auto [t, v] = q.top();
q.pop();
--v;
++ans;
if (v && t > i) q.emplace(t, v);
if (v && t > i) {
q.emplace(t, v);
}
}
++i;
}
return ans;
}
};
};
Loading