Skip to content

feat: add solutions to lc problem: No.2819 #1464

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
Aug 18, 2023
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 @@ -70,34 +70,230 @@ It can be shown that these are the minimum possible relative losses.

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

**方法一:排序 + 二分查找 + 前缀和**

根据题目描述,我们可以知道:

如果 $prices[i] \leq k$,那么 Bob 需要支付 $prices[i]$,而 Alice 不需要支付。因此 Bob 的相对损失为 $prices[i]$。在这种情况下,Bob 应该选择价格较低的巧克力,才能最小化相对损失。

如果 $prices[i] \gt k$,那么 Bob 需要支付 $k$,而 Alice 需要支付 $prices[i] - k$。因此 Bob 的相对损失为 $k - (prices[i] - k) = 2k - prices[i]$。在这种情况下,Bob 应该选择价格较高的巧克力,才能最小化相对损失。

因此,我们先对价格数组 $prices$ 进行排序,然后预处理出前缀和数组 $s$,其中 $s[i]$ 表示前 $i$ 个巧克力的价格之和。

接下来,对于每个询问 $[k, m]$,我们先使用二分查找,找到第一个价格大于 $k$ 的巧克力的下标 $r$。然后,再利用二分查找,找到左侧应该选择的巧克力的数量 $l$,那么右侧应该选择的巧克力的数量就是 $m - l$。此时,Bob 的相对损失为 $s[l] + 2k(m - l) - (s[n] - s[n - (m - l)])$。

上述第二次二分查找的过程中,我们需要判断 $prices[mid] \lt 2k - prices[n - (m - mid)]$,其中 $right$ 表示右侧应该选择的巧克力的数量。如果该不等式成立,那么说明选择 $mid$ 位置的巧克力的相对损失较低,此时更新 $l = mid + 1$。否则,说明 $mid$ 位置的巧克力的相对损失较高,此时更新 $r = mid$。

时间复杂度 $O((n + m) \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 $prices$ 和 $queries$ 的长度。

<!-- tabs:start -->

### **Python3**

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

```python

class Solution:
def minimumRelativeLosses(
self, prices: List[int], queries: List[List[int]]
) -> List[int]:
def f(k: int, m: int) -> int:
l, r = 0, min(m, bisect_right(prices, k))
while l < r:
mid = (l + r) >> 1
right = m - mid
if prices[mid] < 2 * k - prices[n - right]:
l = mid + 1
else:
r = mid
return l

prices.sort()
s = list(accumulate(prices, initial=0))
ans = []
n = len(prices)
for k, m in queries:
l = f(k, m)
r = m - l
loss = s[l] + 2 * k * r - (s[n] - s[n - r])
ans.append(loss)
return ans
```

### **Java**

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

```java

class Solution {
private int n;
private int[] prices;

public long[] minimumRelativeLosses(int[] prices, int[][] queries) {
n = prices.length;
Arrays.sort(prices);
this.prices = prices;
long[] s = new long[n + 1];
for (int i = 0; i < n; ++i) {
s[i + 1] = s[i] + prices[i];
}
int q = queries.length;
long[] ans = new long[q];
for (int i = 0; i < q; ++i) {
int k = queries[i][0], m = queries[i][1];
int l = f(k, m);
int r = m - l;
ans[i] = s[l] + 2L * k * r - (s[n] - s[n - r]);
}
return ans;
}

private int f(int k, int m) {
int l = 0, r = Arrays.binarySearch(prices, k);
if (r < 0) {
r = -(r + 1);
}
r = Math.min(m, r);
while (l < r) {
int mid = (l + r) >> 1;
int right = m - mid;
if (prices[mid] < 2L * k - prices[n - right]) {
l = mid + 1;
} else {
r = mid;
}
}
return l;
}
}
```

### **C++**

```cpp

class Solution {
public:
vector<long long> minimumRelativeLosses(vector<int>& prices, vector<vector<int>>& queries) {
int n = prices.size();
sort(prices.begin(), prices.end());
long long s[n + 1];
s[0] = 0;
for (int i = 1; i <= n; ++i) {
s[i] = s[i - 1] + prices[i - 1];
}
auto f = [&](int k, int m) {
int l = 0, r = upper_bound(prices.begin(), prices.end(), k) - prices.begin();
r = min(r, m);
while (l < r) {
int mid = (l + r) >> 1;
int right = m - mid;
if (prices[mid] < 2LL * k - prices[n - right]) {
l = mid + 1;
} else {
r = mid;
}
}
return l;
};
vector<long long> ans;
for (auto& q : queries) {
int k = q[0], m = q[1];
int l = f(k, m);
int r = m - l;
ans.push_back(s[l] + 2LL * k * r - (s[n] - s[n - r]));
}
return ans;
}
};
```

### **Go**

```go
func minimumRelativeLosses(prices []int, queries [][]int) []int64 {
n := len(prices)
sort.Ints(prices)
s := make([]int, n+1)
for i, x := range prices {
s[i+1] = s[i] + x
}
f := func(k, m int) int {
l, r := 0, sort.Search(n, func(i int) bool { return prices[i] > k })
if r > m {
r = m
}
for l < r {
mid := (l + r) >> 1
right := m - mid
if prices[mid] < 2*k-prices[n-right] {
l = mid + 1
} else {
r = mid
}
}
return l
}
ans := make([]int64, len(queries))
for i, q := range queries {
k, m := q[0], q[1]
l := f(k, m)
r := m - l
ans[i] = int64(s[l] + 2*k*r - (s[n] - s[n-r]))
}
return ans
}
```

### **TypeScript**

```ts
function minimumRelativeLosses(
prices: number[],
queries: number[][],
): number[] {
const n = prices.length;
prices.sort((a, b) => a - b);
const s: number[] = Array(n).fill(0);
for (let i = 0; i < n; ++i) {
s[i + 1] = s[i] + prices[i];
}

const search = (x: number): number => {
let l = 0;
let r = n;
while (l < r) {
const mid = (l + r) >> 1;
if (prices[mid] > x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
};

const f = (k: number, m: number): number => {
let l = 0;
let r = Math.min(search(k), m);
while (l < r) {
const mid = (l + r) >> 1;
const right = m - mid;
if (prices[mid] < 2 * k - prices[n - right]) {
l = mid + 1;
} else {
r = mid;
}
}
return l;
};
const ans: number[] = [];
for (const [k, m] of queries) {
const l = f(k, m);
const r = m - l;
ans.push(s[l] + 2 * k * r - (s[n] - s[n - r]));
}
return ans;
}
```

### **...**
Expand Down
Loading