60
60
61
61
## 解法
62
62
63
- ### 方法一:排序 + 二分查找
63
+ ### 方法一:排序 + 离线查询
64
+
65
+ 对于每一个查询,我们需要找到价格小于等于查询价格的物品中的最大美丽值,我们不妨采用离线查询的方式,先对物品按价格排序,然后对查询按照价格排序。
66
+
67
+ 接下来,我们从小到大遍历查询,对于每一个查询,我们用一个指针 $i$ 指向物品数组,如果物品的价格小于等于查询价格,我们更新当前的最大美丽值,向右移动指针 $i$,直到物品的价格大于查询价格,我们将当前的最大美丽值记录下来,就是当前查询的答案。继续遍历下一个查询,直到所有的查询都处理完。
68
+
69
+ 时间复杂度 $(n \times \log n + m \times \log m)$,空间复杂度 $O(\log n + m)$。其中 $n$ 和 $m$ 分别为物品数组和查询数组的长度。
64
70
65
71
<!-- tabs:start -->
66
72
67
73
``` python
68
74
class Solution :
69
75
def maximumBeauty (self , items : List[List[int ]], queries : List[int ]) -> List[int ]:
70
76
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)
75
78
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
80
85
return ans
81
86
```
82
87
83
88
``` java
84
89
class Solution {
85
90
public int [] maximumBeauty (int [][] items , int [] queries ) {
86
91
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;
89
98
}
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;
104
105
}
106
+ ans[j] = mx;
105
107
}
106
108
return ans;
107
109
}
@@ -113,19 +115,21 @@ class Solution {
113
115
public:
114
116
vector<int > maximumBeauty(vector<vector<int >>& items, vector<int >& queries) {
115
117
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;
127
131
}
128
- if (left) ans[ i ] = items [ left - 1 ] [ 1 ] ;
132
+ ans[ j ] = mx ;
129
133
}
130
134
return ans;
131
135
}
@@ -137,29 +141,168 @@ func maximumBeauty(items [][]int, queries []int) []int {
137
141
sort.Slice(items, func(i, j int) bool {
138
142
return items[i][0] < items[j][0]
139
143
})
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
142
148
}
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++
154
156
}
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]
157
275
}
158
276
}
159
277
return ans
160
278
}
161
279
```
162
280
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
+
163
306
<!-- tabs: end -->
164
307
165
308
<!-- end -->
0 commit comments