Skip to content

Commit f7db1f5

Browse files
committed
src/bin/insert-delete-getrandom-o1-duplicates-allowed.rs
1 parent a379fbf commit f7db1f5

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use rand::Rng;
2+
3+
fn main() {
4+
let mut r = RandomizedCollection::new();
5+
assert!(r.insert(1));
6+
assert!(!r.insert(1));
7+
assert!(r.insert(2));
8+
assert!(r.remove(1));
9+
println!("{}", r.get_random());
10+
println!("{}", r.get_random());
11+
println!("{}", r.get_random());
12+
println!("{}", rand::thread_rng().gen_range(0..10));
13+
println!("{}", rand::thread_rng().gen_range(0..10));
14+
println!("{}", rand::thread_rng().gen_range(0..10));
15+
println!("{}", rand::thread_rng().gen_range(0..10));
16+
}
17+
18+
/**
19+
* Your RandomizedCollection object will be instantiated and called as such:
20+
* let obj = RandomizedCollection::new();
21+
* let ret_1: bool = obj.insert(val);
22+
* let ret_2: bool = obj.remove(val);
23+
* let ret_3: i32 = obj.get_random();
24+
*/
25+
struct RandomizedCollection {
26+
data: Vec<i32>,
27+
indexes: std::collections::HashMap<i32, std::collections::HashMap<usize, ()>>,
28+
}
29+
30+
31+
/**
32+
* `&self` means the method takes an immutable reference.
33+
* If you need a mutable reference, change it to `&mut self` instead.
34+
*/
35+
impl RandomizedCollection {
36+
/** Initialize your data structure here. */
37+
fn new() -> Self {
38+
Self {
39+
data: Vec::new(),
40+
indexes: std::collections::HashMap::new(),
41+
}
42+
}
43+
44+
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
45+
fn insert(&mut self, val: i32) -> bool {
46+
let has = self.indexes.get(&val).is_some();
47+
self.data.push(val);
48+
let index = self.data.len() - 1;
49+
self.indexes.entry(val)
50+
.and_modify(|i| { i.insert(index, ()); })
51+
.or_insert_with(|| {
52+
let mut h = std::collections::HashMap::new();
53+
h.insert(index, ());
54+
h
55+
});
56+
57+
!has
58+
}
59+
60+
/** Removes a value from the collection. Returns true if the collection contained the specified element. */
61+
fn remove(&mut self, val: i32) -> bool {
62+
if self.indexes.get(&val).is_none() { return false; }
63+
64+
let index = {
65+
let i = *self.indexes.get(&val).unwrap().keys().next().unwrap();
66+
self.indexes.get_mut(&val).unwrap().remove(&i);
67+
i
68+
};
69+
let l = self.data.len() - 1;
70+
let last = self.data[l];
71+
self.data.swap(index, l);
72+
73+
if l != index {
74+
self.indexes.entry(last).and_modify(|x| {
75+
x.remove(&l);
76+
x.insert(index, ());
77+
});
78+
}
79+
80+
self.data.pop();
81+
82+
if self.indexes.get(&val).unwrap().is_empty() {
83+
self.indexes.remove(&val);
84+
}
85+
86+
true
87+
}
88+
89+
/** Get a random element from the collection. */
90+
fn get_random(&self) -> i32 {
91+
use rand::Rng;
92+
let mut rng = rand::thread_rng();
93+
let index = rng.gen_range(0..self.data.len());
94+
self.data[index]
95+
}
96+
}

0 commit comments

Comments
 (0)