Skip to content

Commit 22e4e63

Browse files
committed
LC 2070. Most Beautiful Item for Each Query (Rust)
1 parent 4280167 commit 22e4e63

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ to the solution in this repository.
659659
| [2028. Find Missing Observations][lc2028] | 🟠 Medium | [![rust](res/rs.png)][lc2028rs] |
660660
| [2037. Minimum Number of Moves to Seat Everyone][lc2037] | 🟢 Easy | [![rust](res/rs.png)][lc2037rs] |
661661
| [2050. Parallel Courses III][lc2050] | 🔴 Hard | [![rust](res/rs.png)][lc2050rs] |
662+
| [2070. Most Beautiful Item for Each Query][lc2070] | 🟠 Medium | [![rust](res/rs.png)][lc2070rs] |
662663
| [2090. K Radius Subarray Averages][lc2090] | 🟠 Medium | [![rust](res/rs.png)][lc2090rs] |
663664
| [2092. Find All People With Secret][lc2092] | 🔴 Hard | [![rust](res/rs.png)][lc2092rs] |
664665
| [2095. Delete the Middle Node of a Linked List][lc2095] | 🟠 Medium | [![python](res/py.png)][lc2095py] |
@@ -2238,6 +2239,8 @@ to the solution in this repository.
22382239
[lc2037rs]: leetcode/minimum-number-of-moves-to-seat-everyone.rs
22392240
[lc2050]: https://leetcode.com/problems/parallel-courses-iii/
22402241
[lc2050rs]: leetcode/parallel-courses-iii.rs
2242+
[lc2070]: https://leetcode.com/problems/most-beautiful-item-for-each-query/
2243+
[lc2070rs]: leetcode/most-beautiful-item-for-each-query.rs
22412244
[lc2090]: https://leetcode.com/problems/k-radius-subarray-averages/
22422245
[lc2090rs]: leetcode/k-radius-subarray-averages.rs
22432246
[lc2092]: https://leetcode.com/problems/find-all-people-with-secret/
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// 2070. Most Beautiful Item for Each Query
2+
// 🟠 Medium
3+
//
4+
// https://leetcode.com/problems/most-beautiful-item-for-each-query/
5+
//
6+
// Tags: Array - Binary Search - Sorting
7+
8+
struct Solution;
9+
impl Solution {
10+
/// Sort the items vector and remove redundant items, only keep items that maximize the beauty
11+
/// for the given price, we could do the same with a prefix "max" vector, but we can also just
12+
/// remove items that we will never want to pick. After that, use binary search to find the
13+
/// item with the highest price we can afford, given the filtering, that is guaranteed to also
14+
/// have the highest beauty.
15+
///
16+
/// Time complexity: O(m*log(n)+n*log(n)) - First we sort the items vector with n items. Then
17+
/// we filter them in O(n), then we iterate over m queries, for each, we search the query
18+
/// result using binary search in log(n).
19+
/// Space complexity: O(n) - The sorted then filtered items vector.
20+
///
21+
/// Runtime 12 ms Beats 100%
22+
/// Memory 9.73 MB Beats 100%
23+
pub fn maximum_beauty(mut items: Vec<Vec<i32>>, queries: Vec<i32>) -> Vec<i32> {
24+
// Sort by price, then beauty.
25+
items.sort_unstable();
26+
let mut filtered: Vec<Vec<i32>> = Vec::with_capacity(items.len());
27+
for item in items {
28+
while let Some(last) = filtered.last() {
29+
if last[0] == item[0] && last[1] <= item[1] {
30+
filtered.pop();
31+
} else {
32+
if last[1] < item[1] {
33+
filtered.push(item.clone());
34+
}
35+
break;
36+
}
37+
}
38+
if filtered.is_empty() {
39+
filtered.push(item);
40+
}
41+
}
42+
// println!("{:?}", filtered);
43+
queries
44+
.into_iter()
45+
.map(|q| match filtered.partition_point(|x| q + 1 > x[0]) {
46+
0 => 0i32,
47+
idx => filtered[idx - 1][1],
48+
})
49+
.collect()
50+
}
51+
}
52+
53+
// Tests.
54+
fn main() {
55+
let tests = [
56+
(
57+
vec![[1, 2], [3, 2], [2, 4], [5, 6], [3, 5]],
58+
vec![1, 2, 3, 4, 5, 6],
59+
vec![2, 4, 5, 5, 6, 6],
60+
),
61+
(vec![[1, 2], [1, 2], [1, 3], [1, 4]], vec![1], vec![4]),
62+
(vec![[10, 100]], vec![5], vec![0]),
63+
(
64+
vec![
65+
[193, 732],
66+
[781, 962],
67+
[864, 954],
68+
[749, 627],
69+
[136, 746],
70+
[478, 548],
71+
[640, 908],
72+
[210, 799],
73+
[567, 715],
74+
[914, 388],
75+
[487, 853],
76+
[533, 554],
77+
[247, 919],
78+
[958, 150],
79+
[193, 523],
80+
[176, 656],
81+
[395, 469],
82+
[763, 821],
83+
[542, 946],
84+
[701, 676],
85+
],
86+
vec![
87+
885, 1445, 1580, 1309, 205, 1788, 1214, 1404, 572, 1170, 989, 265, 153, 151, 1479,
88+
1180, 875, 276, 1584,
89+
],
90+
vec![
91+
962, 962, 962, 962, 746, 962, 962, 962, 946, 962, 962, 919, 746, 746, 962, 962,
92+
962, 919, 962,
93+
],
94+
),
95+
];
96+
println!("\n\x1b[92m» Running {} tests...\x1b[0m", tests.len());
97+
let mut success = 0;
98+
for (i, t) in tests.iter().enumerate() {
99+
let res = Solution::maximum_beauty(t.0.iter().map(|a| a.to_vec()).collect(), t.1.clone());
100+
if res == t.2 {
101+
success += 1;
102+
println!("\x1b[92m✔\x1b[95m Test {} passed!\x1b[0m", i);
103+
} else {
104+
println!(
105+
"\x1b[31mx\x1b[95m Test {} failed expected: {:?} but got {:?}!!\x1b[0m",
106+
i, t.2, res
107+
);
108+
}
109+
}
110+
println!();
111+
if success == tests.len() {
112+
println!("\x1b[30;42m✔ All tests passed!\x1b[0m")
113+
} else if success == 0 {
114+
println!("\x1b[31mx \x1b[41;37mAll tests failed!\x1b[0m")
115+
} else {
116+
println!(
117+
"\x1b[31mx\x1b[95m {} tests failed!\x1b[0m",
118+
tests.len() - success
119+
)
120+
}
121+
}

0 commit comments

Comments
 (0)