|
| 1 | +# [2838. Maximum Coins Heroes Can Collect](https://leetcode.cn/problems/maximum-coins-heroes-can-collect) |
| 2 | + |
| 3 | +[English Version](/solution/2800-2899/2838.Maximum%20Coins%20Heroes%20Can%20Collect/README_EN.md) |
| 4 | + |
| 5 | +## 题目描述 |
| 6 | + |
| 7 | +<!-- 这里写题目描述 --> |
| 8 | + |
| 9 | +<p>There is a battle and <code>n</code> heroes are trying to defeat <code>m</code> monsters. You are given two <strong>1-indexed</strong> arrays of <strong>positive</strong> integers <code><font face="monospace">heroes</font></code> and <code><font face="monospace">monsters</font></code> of length <code>n</code> and <code>m</code>, respectively. <code><font face="monospace">heroes</font>[i]</code> is the power of <code>i<sup>th</sup></code> hero, and <code><font face="monospace">monsters</font>[i]</code> is the power of <code>i<sup>th</sup></code> monster.</p> |
| 10 | + |
| 11 | +<p>The <code>i<sup>th</sup></code> hero can defeat the <code>j<sup>th</sup></code> monster if <code>monsters[j] <= heroes[i]</code>.</p> |
| 12 | + |
| 13 | +<p>You are also given a <strong>1-indexed</strong> array <code>coins</code> of length <code>m</code> consisting of <strong>positive</strong> integers. <code>coins[i]</code> is the number of coins that each hero earns after defeating the <code>i<sup>th</sup></code> monster.</p> |
| 14 | + |
| 15 | +<p>Return<em> an array </em><code>ans</code><em> of length </em><code>n</code><em> where </em><code>ans[i]</code><em> is the <strong>maximum</strong> number of coins that the </em><code>i<sup>th</sup></code><em> hero can collect from this battle</em>.</p> |
| 16 | + |
| 17 | +<p><strong>Notes</strong></p> |
| 18 | + |
| 19 | +<ul> |
| 20 | + <li>The health of a hero doesn't get reduced after defeating a monster.</li> |
| 21 | + <li>Multiple heroes can defeat a monster, but each monster can be defeated by a given hero only once.</li> |
| 22 | +</ul> |
| 23 | + |
| 24 | +<p> </p> |
| 25 | +<p><strong class="example">Example 1:</strong></p> |
| 26 | + |
| 27 | +<pre> |
| 28 | +<strong>Input:</strong> heroes = [1,4,2], monsters = [1,1,5,2,3], coins = [2,3,4,5,6] |
| 29 | +<strong>Output:</strong> [5,16,10] |
| 30 | +<strong>Explanation: </strong>For each hero, we list the index of all the monsters he can defeat: |
| 31 | +1<sup>st</sup> hero: [1,2] since the power of this hero is 1 and monsters[1], monsters[2] <= 1. So this hero collects coins[1] + coins[2] = 5 coins. |
| 32 | +2<sup>nd</sup> hero: [1,2,4,5] since the power of this hero is 4 and monsters[1], monsters[2], monsters[4], monsters[5] <= 4. So this hero collects coins[1] + coins[2] + coins[4] + coins[5] = 16 coins. |
| 33 | +3<sup>rd</sup> hero: [1,2,4] since the power of this hero is 2 and monsters[1], monsters[2], monsters[4] <= 2. So this hero collects coins[1] + coins[2] + coins[4] = 10 coins. |
| 34 | +So the answer would be [5,16,10].</pre> |
| 35 | + |
| 36 | +<p><strong class="example">Example 2:</strong></p> |
| 37 | + |
| 38 | +<pre> |
| 39 | +<strong>Input:</strong> heroes = [5], monsters = [2,3,1,2], coins = [10,6,5,2] |
| 40 | +<strong>Output:</strong> [23] |
| 41 | +<strong>Explanation:</strong> This hero can defeat all the monsters since monsters[i] <= 5. So he collects all of the coins: coins[1] + coins[2] + coins[3] + coins[4] = 23, and the answer would be [23]. |
| 42 | +</pre> |
| 43 | + |
| 44 | +<p><strong class="example">Example 3:</strong></p> |
| 45 | + |
| 46 | +<pre> |
| 47 | +<strong>Input:</strong> heroes = [4,4], monsters = [5,7,8], coins = [1,1,1] |
| 48 | +<strong>Output:</strong> [0,0] |
| 49 | +<strong>Explanation:</strong> In this example, no hero can defeat a monster. So the answer would be [0,0], |
| 50 | +</pre> |
| 51 | + |
| 52 | +<p> </p> |
| 53 | +<p><strong>Constraints:</strong></p> |
| 54 | + |
| 55 | +<ul> |
| 56 | + <li><code>1 <= n == heroes.length <= 10<sup>5</sup></code></li> |
| 57 | + <li><code>1 <= m == monsters.length <= 10<sup>5</sup></code></li> |
| 58 | + <li><code>coins.length == m</code></li> |
| 59 | + <li><code>1 <= heroes[i], monsters[i], coins[i] <= 10<sup>9</sup></code></li> |
| 60 | +</ul> |
| 61 | + |
| 62 | +## 解法 |
| 63 | + |
| 64 | +<!-- 这里可写通用的实现逻辑 --> |
| 65 | + |
| 66 | +**方法一:排序 + 前缀和 + 二分查找** |
| 67 | + |
| 68 | +我们可以将怪物和金币按照怪物的战斗力从小到大排序,然后使用前缀和计算每个英雄打败前 $i$ 个怪物可以获得的金币总数。 |
| 69 | + |
| 70 | +接下来,对于每个英雄,我们可以使用二分查找找到他可以打败的最大的怪物,然后使用前缀和计算他可以获得的金币总数即可。 |
| 71 | + |
| 72 | +时间复杂度 $O((m + n) \times \log n)$,空间复杂度 $O(m)$。其中 $m$ 和 $n$ 分别是怪物和英雄的数量。 |
| 73 | + |
| 74 | +<!-- tabs:start --> |
| 75 | + |
| 76 | +### **Python3** |
| 77 | + |
| 78 | +<!-- 这里可写当前语言的特殊实现逻辑 --> |
| 79 | + |
| 80 | +```python |
| 81 | +class Solution: |
| 82 | + def maximumCoins( |
| 83 | + self, heroes: List[int], monsters: List[int], coins: List[int] |
| 84 | + ) -> List[int]: |
| 85 | + m = len(monsters) |
| 86 | + idx = sorted(range(m), key=lambda i: monsters[i]) |
| 87 | + s = list(accumulate((coins[i] for i in idx), initial=0)) |
| 88 | + ans = [] |
| 89 | + for h in heroes: |
| 90 | + i = bisect_right(idx, h, key=lambda i: monsters[i]) |
| 91 | + ans.append(s[i]) |
| 92 | + return ans |
| 93 | +``` |
| 94 | + |
| 95 | +### **Java** |
| 96 | + |
| 97 | +<!-- 这里可写当前语言的特殊实现逻辑 --> |
| 98 | + |
| 99 | +```java |
| 100 | +class Solution { |
| 101 | + public long[] maximumCoins(int[] heroes, int[] monsters, int[] coins) { |
| 102 | + int m = monsters.length; |
| 103 | + Integer[] idx = new Integer[m]; |
| 104 | + for (int i = 0; i < m; ++i) { |
| 105 | + idx[i] = i; |
| 106 | + } |
| 107 | + |
| 108 | + Arrays.sort(idx, Comparator.comparingInt(j -> monsters[j])); |
| 109 | + long[] s = new long[m + 1]; |
| 110 | + for (int i = 0; i < m; ++i) { |
| 111 | + s[i + 1] = s[i] + coins[idx[i]]; |
| 112 | + } |
| 113 | + int n = heroes.length; |
| 114 | + long[] ans = new long[n]; |
| 115 | + for (int k = 0; k < n; ++k) { |
| 116 | + int i = search(monsters, idx, heroes[k]); |
| 117 | + ans[k] = s[i]; |
| 118 | + } |
| 119 | + return ans; |
| 120 | + } |
| 121 | + |
| 122 | + private int search(int[] nums, Integer[] idx, int x) { |
| 123 | + int l = 0, r = idx.length; |
| 124 | + while (l < r) { |
| 125 | + int mid = (l + r) >> 1; |
| 126 | + if (nums[idx[mid]] > x) { |
| 127 | + r = mid; |
| 128 | + } else { |
| 129 | + l = mid + 1; |
| 130 | + } |
| 131 | + } |
| 132 | + return l; |
| 133 | + } |
| 134 | +} |
| 135 | +``` |
| 136 | + |
| 137 | +### **C++** |
| 138 | + |
| 139 | +```cpp |
| 140 | +class Solution { |
| 141 | +public: |
| 142 | + vector<long long> maximumCoins(vector<int>& heroes, vector<int>& monsters, vector<int>& coins) { |
| 143 | + int m = monsters.size(); |
| 144 | + vector<int> idx(m); |
| 145 | + iota(idx.begin(), idx.end(), 0); |
| 146 | + sort(idx.begin(), idx.end(), [&](int i, int j) { |
| 147 | + return monsters[i] < monsters[j]; |
| 148 | + }); |
| 149 | + long long s[m + 1]; |
| 150 | + s[0] = 0; |
| 151 | + for (int i = 1; i <= m; ++i) { |
| 152 | + s[i] = s[i - 1] + coins[idx[i - 1]]; |
| 153 | + } |
| 154 | + vector<long long> ans; |
| 155 | + auto search = [&](int x) { |
| 156 | + int l = 0, r = m; |
| 157 | + while (l < r) { |
| 158 | + int mid = (l + r) >> 1; |
| 159 | + if (monsters[idx[mid]] > x) { |
| 160 | + r = mid; |
| 161 | + } else { |
| 162 | + l = mid + 1; |
| 163 | + } |
| 164 | + } |
| 165 | + return l; |
| 166 | + }; |
| 167 | + for (int h : heroes) { |
| 168 | + ans.push_back(s[search(h)]); |
| 169 | + } |
| 170 | + return ans; |
| 171 | + } |
| 172 | +}; |
| 173 | +``` |
| 174 | +
|
| 175 | +### **Go** |
| 176 | +
|
| 177 | +```go |
| 178 | +func maximumCoins(heroes []int, monsters []int, coins []int) (ans []int64) { |
| 179 | + m := len(monsters) |
| 180 | + idx := make([]int, m) |
| 181 | + for i := range idx { |
| 182 | + idx[i] = i |
| 183 | + } |
| 184 | + sort.Slice(idx, func(i, j int) bool { return monsters[idx[i]] < monsters[idx[j]] }) |
| 185 | + s := make([]int64, m+1) |
| 186 | + for i, j := range idx { |
| 187 | + s[i+1] = s[i] + int64(coins[j]) |
| 188 | + } |
| 189 | + for _, h := range heroes { |
| 190 | + i := sort.Search(m, func(i int) bool { return monsters[idx[i]] > h }) |
| 191 | + ans = append(ans, s[i]) |
| 192 | + } |
| 193 | + return |
| 194 | +} |
| 195 | +``` |
| 196 | + |
| 197 | +### **TypeScript** |
| 198 | + |
| 199 | +```ts |
| 200 | +function maximumCoins( |
| 201 | + heroes: number[], |
| 202 | + monsters: number[], |
| 203 | + coins: number[], |
| 204 | +): number[] { |
| 205 | + const m = monsters.length; |
| 206 | + const idx: number[] = Array.from({ length: m }, (_, i) => i); |
| 207 | + idx.sort((i, j) => monsters[i] - monsters[j]); |
| 208 | + const s: number[] = Array(m + 1).fill(0); |
| 209 | + for (let i = 0; i < m; ++i) { |
| 210 | + s[i + 1] = s[i] + coins[idx[i]]; |
| 211 | + } |
| 212 | + const search = (x: number): number => { |
| 213 | + let l = 0; |
| 214 | + let r = m; |
| 215 | + while (l < r) { |
| 216 | + const mid = (l + r) >> 1; |
| 217 | + if (monsters[idx[mid]] > x) { |
| 218 | + r = mid; |
| 219 | + } else { |
| 220 | + l = mid + 1; |
| 221 | + } |
| 222 | + } |
| 223 | + return l; |
| 224 | + }; |
| 225 | + return heroes.map(h => s[search(h)]); |
| 226 | +} |
| 227 | +``` |
| 228 | + |
| 229 | +### **...** |
| 230 | + |
| 231 | +``` |
| 232 | +
|
| 233 | +``` |
| 234 | + |
| 235 | +<!-- tabs:end --> |
0 commit comments