Skip to content

Commit 285f8e1

Browse files
authored
feat: add solutions to lc problem: No.2819 (#1464)
No.2819.Minimum Relative Loss After Buying Chocolates
1 parent 33f23b0 commit 285f8e1

File tree

7 files changed

+561
-6
lines changed

7 files changed

+561
-6
lines changed

solution/2800-2899/2819.Minimum Relative Loss After Buying Chocolates/README.md

+199-3
Original file line numberDiff line numberDiff line change
@@ -70,34 +70,230 @@ It can be shown that these are the minimum possible relative losses.
7070

7171
<!-- 这里可写通用的实现逻辑 -->
7272

73+
**方法一:排序 + 二分查找 + 前缀和**
74+
75+
根据题目描述,我们可以知道:
76+
77+
如果 $prices[i] \leq k$,那么 Bob 需要支付 $prices[i]$,而 Alice 不需要支付。因此 Bob 的相对损失为 $prices[i]$。在这种情况下,Bob 应该选择价格较低的巧克力,才能最小化相对损失。
78+
79+
如果 $prices[i] \gt k$,那么 Bob 需要支付 $k$,而 Alice 需要支付 $prices[i] - k$。因此 Bob 的相对损失为 $k - (prices[i] - k) = 2k - prices[i]$。在这种情况下,Bob 应该选择价格较高的巧克力,才能最小化相对损失。
80+
81+
因此,我们先对价格数组 $prices$ 进行排序,然后预处理出前缀和数组 $s$,其中 $s[i]$ 表示前 $i$ 个巧克力的价格之和。
82+
83+
接下来,对于每个询问 $[k, m]$,我们先使用二分查找,找到第一个价格大于 $k$ 的巧克力的下标 $r$。然后,再利用二分查找,找到左侧应该选择的巧克力的数量 $l$,那么右侧应该选择的巧克力的数量就是 $m - l$。此时,Bob 的相对损失为 $s[l] + 2k(m - l) - (s[n] - s[n - (m - l)])$。
84+
85+
上述第二次二分查找的过程中,我们需要判断 $prices[mid] \lt 2k - prices[n - (m - mid)]$,其中 $right$ 表示右侧应该选择的巧克力的数量。如果该不等式成立,那么说明选择 $mid$ 位置的巧克力的相对损失较低,此时更新 $l = mid + 1$。否则,说明 $mid$ 位置的巧克力的相对损失较高,此时更新 $r = mid$。
86+
87+
时间复杂度 $O((n + m) \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 $prices$ 和 $queries$ 的长度。
88+
7389
<!-- tabs:start -->
7490

7591
### **Python3**
7692

7793
<!-- 这里可写当前语言的特殊实现逻辑 -->
7894

7995
```python
80-
96+
class Solution:
97+
def minimumRelativeLosses(
98+
self, prices: List[int], queries: List[List[int]]
99+
) -> List[int]:
100+
def f(k: int, m: int) -> int:
101+
l, r = 0, min(m, bisect_right(prices, k))
102+
while l < r:
103+
mid = (l + r) >> 1
104+
right = m - mid
105+
if prices[mid] < 2 * k - prices[n - right]:
106+
l = mid + 1
107+
else:
108+
r = mid
109+
return l
110+
111+
prices.sort()
112+
s = list(accumulate(prices, initial=0))
113+
ans = []
114+
n = len(prices)
115+
for k, m in queries:
116+
l = f(k, m)
117+
r = m - l
118+
loss = s[l] + 2 * k * r - (s[n] - s[n - r])
119+
ans.append(loss)
120+
return ans
81121
```
82122

83123
### **Java**
84124

85125
<!-- 这里可写当前语言的特殊实现逻辑 -->
86126

87127
```java
88-
128+
class Solution {
129+
private int n;
130+
private int[] prices;
131+
132+
public long[] minimumRelativeLosses(int[] prices, int[][] queries) {
133+
n = prices.length;
134+
Arrays.sort(prices);
135+
this.prices = prices;
136+
long[] s = new long[n + 1];
137+
for (int i = 0; i < n; ++i) {
138+
s[i + 1] = s[i] + prices[i];
139+
}
140+
int q = queries.length;
141+
long[] ans = new long[q];
142+
for (int i = 0; i < q; ++i) {
143+
int k = queries[i][0], m = queries[i][1];
144+
int l = f(k, m);
145+
int r = m - l;
146+
ans[i] = s[l] + 2L * k * r - (s[n] - s[n - r]);
147+
}
148+
return ans;
149+
}
150+
151+
private int f(int k, int m) {
152+
int l = 0, r = Arrays.binarySearch(prices, k);
153+
if (r < 0) {
154+
r = -(r + 1);
155+
}
156+
r = Math.min(m, r);
157+
while (l < r) {
158+
int mid = (l + r) >> 1;
159+
int right = m - mid;
160+
if (prices[mid] < 2L * k - prices[n - right]) {
161+
l = mid + 1;
162+
} else {
163+
r = mid;
164+
}
165+
}
166+
return l;
167+
}
168+
}
89169
```
90170

91171
### **C++**
92172

93173
```cpp
94-
174+
class Solution {
175+
public:
176+
vector<long long> minimumRelativeLosses(vector<int>& prices, vector<vector<int>>& queries) {
177+
int n = prices.size();
178+
sort(prices.begin(), prices.end());
179+
long long s[n + 1];
180+
s[0] = 0;
181+
for (int i = 1; i <= n; ++i) {
182+
s[i] = s[i - 1] + prices[i - 1];
183+
}
184+
auto f = [&](int k, int m) {
185+
int l = 0, r = upper_bound(prices.begin(), prices.end(), k) - prices.begin();
186+
r = min(r, m);
187+
while (l < r) {
188+
int mid = (l + r) >> 1;
189+
int right = m - mid;
190+
if (prices[mid] < 2LL * k - prices[n - right]) {
191+
l = mid + 1;
192+
} else {
193+
r = mid;
194+
}
195+
}
196+
return l;
197+
};
198+
vector<long long> ans;
199+
for (auto& q : queries) {
200+
int k = q[0], m = q[1];
201+
int l = f(k, m);
202+
int r = m - l;
203+
ans.push_back(s[l] + 2LL * k * r - (s[n] - s[n - r]));
204+
}
205+
return ans;
206+
}
207+
};
95208
```
96209
97210
### **Go**
98211
99212
```go
213+
func minimumRelativeLosses(prices []int, queries [][]int) []int64 {
214+
n := len(prices)
215+
sort.Ints(prices)
216+
s := make([]int, n+1)
217+
for i, x := range prices {
218+
s[i+1] = s[i] + x
219+
}
220+
f := func(k, m int) int {
221+
l, r := 0, sort.Search(n, func(i int) bool { return prices[i] > k })
222+
if r > m {
223+
r = m
224+
}
225+
for l < r {
226+
mid := (l + r) >> 1
227+
right := m - mid
228+
if prices[mid] < 2*k-prices[n-right] {
229+
l = mid + 1
230+
} else {
231+
r = mid
232+
}
233+
}
234+
return l
235+
}
236+
ans := make([]int64, len(queries))
237+
for i, q := range queries {
238+
k, m := q[0], q[1]
239+
l := f(k, m)
240+
r := m - l
241+
ans[i] = int64(s[l] + 2*k*r - (s[n] - s[n-r]))
242+
}
243+
return ans
244+
}
245+
```
100246

247+
### **TypeScript**
248+
249+
```ts
250+
function minimumRelativeLosses(
251+
prices: number[],
252+
queries: number[][],
253+
): number[] {
254+
const n = prices.length;
255+
prices.sort((a, b) => a - b);
256+
const s: number[] = Array(n).fill(0);
257+
for (let i = 0; i < n; ++i) {
258+
s[i + 1] = s[i] + prices[i];
259+
}
260+
261+
const search = (x: number): number => {
262+
let l = 0;
263+
let r = n;
264+
while (l < r) {
265+
const mid = (l + r) >> 1;
266+
if (prices[mid] > x) {
267+
r = mid;
268+
} else {
269+
l = mid + 1;
270+
}
271+
}
272+
return l;
273+
};
274+
275+
const f = (k: number, m: number): number => {
276+
let l = 0;
277+
let r = Math.min(search(k), m);
278+
while (l < r) {
279+
const mid = (l + r) >> 1;
280+
const right = m - mid;
281+
if (prices[mid] < 2 * k - prices[n - right]) {
282+
l = mid + 1;
283+
} else {
284+
r = mid;
285+
}
286+
}
287+
return l;
288+
};
289+
const ans: number[] = [];
290+
for (const [k, m] of queries) {
291+
const l = f(k, m);
292+
const r = m - l;
293+
ans.push(s[l] + 2 * k * r - (s[n] - s[n - r]));
294+
}
295+
return ans;
296+
}
101297
```
102298

103299
### **...**

0 commit comments

Comments
 (0)