Skip to content

Commit c48370c

Browse files
authored
feat: add solutions to lc problem: No.2070 (#2571)
No.2070.Most Beautiful Item for Each Query
1 parent 9472f7b commit c48370c

File tree

12 files changed

+549
-156
lines changed

12 files changed

+549
-156
lines changed

solution/2000-2099/2070.Most Beautiful Item for Each Query/README.md

+195-52
Original file line numberDiff line numberDiff line change
@@ -60,48 +60,50 @@
6060

6161
## 解法
6262

63-
### 方法一:排序 + 二分查找
63+
### 方法一:排序 + 离线查询
64+
65+
对于每一个查询,我们需要找到价格小于等于查询价格的物品中的最大美丽值,我们不妨采用离线查询的方式,先对物品按价格排序,然后对查询按照价格排序。
66+
67+
接下来,我们从小到大遍历查询,对于每一个查询,我们用一个指针 $i$ 指向物品数组,如果物品的价格小于等于查询价格,我们更新当前的最大美丽值,向右移动指针 $i$,直到物品的价格大于查询价格,我们将当前的最大美丽值记录下来,就是当前查询的答案。继续遍历下一个查询,直到所有的查询都处理完。
68+
69+
时间复杂度 $(n \times \log n + m \times \log m)$,空间复杂度 $O(\log n + m)$。其中 $n$ 和 $m$ 分别为物品数组和查询数组的长度。
6470

6571
<!-- tabs:start -->
6672

6773
```python
6874
class Solution:
6975
def maximumBeauty(self, items: List[List[int]], queries: List[int]) -> List[int]:
7076
items.sort()
71-
prices = [p for p, _ in items]
72-
mx = [items[0][1]]
73-
for _, b in items[1:]:
74-
mx.append(max(mx[-1], b))
77+
n, m = len(items), len(queries)
7578
ans = [0] * len(queries)
76-
for i, q in enumerate(queries):
77-
j = bisect_right(prices, q)
78-
if j:
79-
ans[i] = mx[j - 1]
79+
i = mx = 0
80+
for q, j in sorted(zip(queries, range(m))):
81+
while i < n and items[i][0] <= q:
82+
mx = max(mx, items[i][1])
83+
i += 1
84+
ans[j] = mx
8085
return ans
8186
```
8287

8388
```java
8489
class Solution {
8590
public int[] maximumBeauty(int[][] items, int[] queries) {
8691
Arrays.sort(items, (a, b) -> a[0] - b[0]);
87-
for (int i = 1; i < items.length; ++i) {
88-
items[i][1] = Math.max(items[i - 1][1], items[i][1]);
92+
int n = items.length;
93+
int m = queries.length;
94+
int[] ans = new int[m];
95+
Integer[] idx = new Integer[m];
96+
for (int i = 0; i < m; ++i) {
97+
idx[i] = i;
8998
}
90-
int n = queries.length;
91-
int[] ans = new int[n];
92-
for (int i = 0; i < n; ++i) {
93-
int left = 0, right = items.length;
94-
while (left < right) {
95-
int mid = (left + right) >> 1;
96-
if (items[mid][0] > queries[i]) {
97-
right = mid;
98-
} else {
99-
left = mid + 1;
100-
}
101-
}
102-
if (left > 0) {
103-
ans[i] = items[left - 1][1];
99+
Arrays.sort(idx, (i, j) -> queries[i] - queries[j]);
100+
int i = 0, mx = 0;
101+
for (int j : idx) {
102+
while (i < n && items[i][0] <= queries[j]) {
103+
mx = Math.max(mx, items[i][1]);
104+
++i;
104105
}
106+
ans[j] = mx;
105107
}
106108
return ans;
107109
}
@@ -113,19 +115,21 @@ class Solution {
113115
public:
114116
vector<int> maximumBeauty(vector<vector<int>>& items, vector<int>& queries) {
115117
sort(items.begin(), items.end());
116-
for (int i = 1; i < items.size(); ++i) items[i][1] = max(items[i - 1][1], items[i][1]);
117-
int n = queries.size();
118-
vector<int> ans(n);
119-
for (int i = 0; i < n; ++i) {
120-
int left = 0, right = items.size();
121-
while (left < right) {
122-
int mid = (left + right) >> 1;
123-
if (items[mid][0] > queries[i])
124-
right = mid;
125-
else
126-
left = mid + 1;
118+
int n = items.size();
119+
int m = queries.size();
120+
vector<int> idx(m);
121+
iota(idx.begin(), idx.end(), 0);
122+
sort(idx.begin(), idx.end(), [&](int i, int j) {
123+
return queries[i] < queries[j];
124+
});
125+
int mx = 0, i = 0;
126+
vector<int> ans(m);
127+
for (int j : idx) {
128+
while (i < n && items[i][0] <= queries[j]) {
129+
mx = max(mx, items[i][1]);
130+
++i;
127131
}
128-
if (left) ans[i] = items[left - 1][1];
132+
ans[j] = mx;
129133
}
130134
return ans;
131135
}
@@ -137,29 +141,168 @@ func maximumBeauty(items [][]int, queries []int) []int {
137141
sort.Slice(items, func(i, j int) bool {
138142
return items[i][0] < items[j][0]
139143
})
140-
for i := 1; i < len(items); i++ {
141-
items[i][1] = max(items[i-1][1], items[i][1])
144+
n, m := len(items), len(queries)
145+
idx := make([]int, m)
146+
for i := range idx {
147+
idx[i] = i
142148
}
143-
n := len(queries)
144-
ans := make([]int, n)
145-
for i, v := range queries {
146-
left, right := 0, len(items)
147-
for left < right {
148-
mid := (left + right) >> 1
149-
if items[mid][0] > v {
150-
right = mid
151-
} else {
152-
left = mid + 1
153-
}
149+
sort.Slice(idx, func(i, j int) bool { return queries[idx[i]] < queries[idx[j]] })
150+
ans := make([]int, m)
151+
i, mx := 0, 0
152+
for _, j := range idx {
153+
for i < n && items[i][0] <= queries[j] {
154+
mx = max(mx, items[i][1])
155+
i++
154156
}
155-
if left > 0 {
156-
ans[i] = items[left-1][1]
157+
ans[j] = mx
158+
}
159+
return ans
160+
}
161+
```
162+
163+
```ts
164+
function maximumBeauty(items: number[][], queries: number[]): number[] {
165+
const n = items.length;
166+
const m = queries.length;
167+
items.sort((a, b) => a[0] - b[0]);
168+
const idx: number[] = Array(m)
169+
.fill(0)
170+
.map((_, i) => i);
171+
idx.sort((i, j) => queries[i] - queries[j]);
172+
let [i, mx] = [0, 0];
173+
const ans: number[] = Array(m).fill(0);
174+
for (const j of idx) {
175+
while (i < n && items[i][0] <= queries[j]) {
176+
mx = Math.max(mx, items[i][1]);
177+
++i;
178+
}
179+
ans[j] = mx;
180+
}
181+
return ans;
182+
}
183+
```
184+
185+
<!-- tabs:end -->
186+
187+
### 方法二:排序 + 二分查找
188+
189+
我们可以将物品按照价格排序,然后预处理出小于等于每个价格的物品中的最大美丽值,记录在数组 $mx$ 或者原 $items$ 数组中。
190+
191+
对于每一个查询,我们可以使用二分查找找到第一个价格大于查询价格的物品的下标 $j$,然后 $j - 1$ 就是小于等于查询价格且最大美丽值的物品的下标,添加到答案中。
192+
193+
时间复杂度 $O((m + n) \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为物品数组和查询数组的长度。
194+
195+
<!-- tabs:start -->
196+
197+
```python
198+
class Solution:
199+
def maximumBeauty(self, items: List[List[int]], queries: List[int]) -> List[int]:
200+
items.sort()
201+
prices = [p for p, _ in items]
202+
n = len(items)
203+
mx = [items[0][1]]
204+
for i in range(1, n):
205+
mx.append(max(mx[i - 1], items[i][1]))
206+
ans = []
207+
for q in queries:
208+
j = bisect_right(prices, q) - 1
209+
ans.append(0 if j < 0 else mx[j])
210+
return ans
211+
```
212+
213+
```java
214+
class Solution {
215+
public int[] maximumBeauty(int[][] items, int[] queries) {
216+
Arrays.sort(items, (a, b) -> a[0] - b[0]);
217+
int n = items.length;
218+
int m = queries.length;
219+
int[] prices = new int[n];
220+
prices[0] = items[0][0];
221+
for (int i = 1; i < n; ++i) {
222+
prices[i] = items[i][0];
223+
items[i][1] = Math.max(items[i - 1][1], items[i][1]);
224+
}
225+
int[] ans = new int[m];
226+
for (int i = 0; i < m; ++i) {
227+
int j = Arrays.binarySearch(prices, queries[i] + 1);
228+
j = j < 0 ? -j - 2 : j - 1;
229+
ans[i] = j < 0 ? 0 : items[j][1];
230+
}
231+
return ans;
232+
}
233+
}
234+
```
235+
236+
```cpp
237+
class Solution {
238+
public:
239+
vector<int> maximumBeauty(vector<vector<int>>& items, vector<int>& queries) {
240+
sort(items.begin(), items.end());
241+
int n = items.size();
242+
int m = queries.size();
243+
vector<int> prices(n, items[0][0]);
244+
for (int i = 1; i < n; ++i) {
245+
prices[i] = items[i][0];
246+
items[i][1] = max(items[i - 1][1], items[i][1]);
247+
}
248+
vector<int> ans;
249+
for (int q : queries) {
250+
int j = upper_bound(prices.begin(), prices.end(), q) - prices.begin() - 1;
251+
ans.push_back(j < 0 ? 0 : items[j][1]);
252+
}
253+
return ans;
254+
}
255+
};
256+
```
257+
258+
```go
259+
func maximumBeauty(items [][]int, queries []int) []int {
260+
sort.Slice(items, func(i, j int) bool {
261+
return items[i][0] < items[j][0]
262+
})
263+
n, m := len(items), len(queries)
264+
prices := make([]int, n)
265+
prices[0] = items[0][0]
266+
for i := 1; i < n; i++ {
267+
prices[i] = items[i][0]
268+
items[i][1] = max(items[i][1], items[i-1][1])
269+
}
270+
ans := make([]int, m)
271+
for i, q := range queries {
272+
j := sort.SearchInts(prices, q+1) - 1
273+
if j >= 0 {
274+
ans[i] = items[j][1]
157275
}
158276
}
159277
return ans
160278
}
161279
```
162280

281+
```ts
282+
function maximumBeauty(items: number[][], queries: number[]): number[] {
283+
items.sort((a, b) => a[0] - b[0]);
284+
const n = items.length;
285+
for (let i = 1; i < n; ++i) {
286+
items[i][1] = Math.max(items[i][1], items[i - 1][1]);
287+
}
288+
const ans: number[] = [];
289+
for (const q of queries) {
290+
let l = 0,
291+
r = n;
292+
while (l < r) {
293+
const mid = (l + r) >> 1;
294+
if (items[mid][0] > q) {
295+
r = mid;
296+
} else {
297+
l = mid + 1;
298+
}
299+
}
300+
ans.push(--l >= 0 ? items[l][1] : 0);
301+
}
302+
return ans;
303+
}
304+
```
305+
163306
<!-- tabs:end -->
164307

165308
<!-- end -->

0 commit comments

Comments
 (0)