leetcode/all_one.rs
1//! # 432. 全 O(1) 的数据结构
2//!
3//! 难度 困难
4//!
5//! 请你实现一个数据结构支持以下操作:
6//!
7//! - Inc(key) - 插入一个新的值为 1 的 key。或者使一个存在的 key 增加一,保证 key 不为空字符串。
8//! - Dec(key) - 如果这个 key 的值是 1,那么把他从数据结构中移除掉。否则使一个存在的 key 值减一。如果这个 key 不存在,这个函数不做任何事情。key 保证不为空字符串。
9//! - GetMaxKey() - 返回 key 中值最大的任意一个。如果没有元素存在,返回一个空字符串"" 。
10//! - GetMinKey() - 返回 key 中值最小的任意一个。如果没有元素存在,返回一个空字符串""。
11//!
12//!
13//! ## 挑战:
14//!
15//! 你能够以 O(1) 的时间复杂度实现所有操作吗?
16//!
17//! See [leetcode](https://leetcode-cn.com/problems/all-oone-data-structure/)
18//!
19use std::ptr::NonNull;
20use std::collections::{
21 HashMap,
22 HashSet,
23};
24
25/// 双向链表 + 两个 HashMap
26///
27/// 本实现使用 `NonNull` 封装裸指针,需要注意在删除节点或者 Drop 整个结构的时候需要用
28/// `Box::from_raw()` 来释放内存。
29///
30/// * `keys: HashMap<String, u32>` 记录该数据结构内所有的 key 对应的值,以便用 O(1) 的时间查找 key
31/// * `index: HashMap<u32, NonNull<Node>>` 记录该数据结构内所有 key 的值(作为 key)在链表结构里对应的节点的指针
32#[derive(Default, Debug)]
33pub struct AllOne {
34 head: Option<NonNull<Node>>,
35 tail: Option<NonNull<Node>>,
36 keys: HashMap<String, u32>,
37 index: HashMap<u32, NonNull<Node>>,
38}
39
40// Guaranteed Send & Sync for AllOne
41unsafe impl Send for AllOne {}
42unsafe impl Sync for AllOne {}
43
44/// 链表节点,节点的值为该节点记录的 key 对应的值,同时记录所有等于该值的 key 的 set。
45#[derive(Default, Debug)]
46struct Node {
47 next: Option<NonNull<Node>>,
48 prev: Option<NonNull<Node>>,
49 value: u32,
50 keys: HashSet<String>,
51}
52
53enum Offset {
54 Inc,
55 Dec,
56}
57
58
59/**
60 * `&self` means the method takes an immutable reference.
61 * If you need a mutable reference, change it to `&mut self` instead.
62 */
63impl AllOne {
64
65 /** Initialize your data structure here. */
66 pub fn new() -> Self {
67 Default::default()
68 }
69
70 /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
71 pub fn inc(&mut self, key: String) {
72 unsafe {
73 self.update_node(&key, Offset::Inc);
74 }
75 }
76
77 /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
78 pub fn dec(&mut self, key: String) {
79 unsafe {
80 self.update_node(&key, Offset::Dec);
81 }
82 }
83
84 /** Returns one of the keys with maximal value. */
85 pub fn get_max_key(&self) -> String {
86 self.tail.as_ref().and_then(|tail| unsafe {
87 (*tail.as_ptr()).keys.iter().next().map(Clone::clone)
88 }).unwrap_or_else(|| "".to_string())
89 }
90
91 /** Returns one of the keys with Minimal value. */
92 pub fn get_min_key(&self) -> String {
93 self.head.as_ref().and_then(|head| unsafe {
94 (*head.as_ptr()).keys.iter().next().map(Clone::clone)
95 }).unwrap_or_else(|| "".to_string())
96 }
97
98 // `pop_head()` will constructs a node from its raw point, which will be destructured
99 // and freed allocated memory correctly.
100 fn pop_head(&mut self) -> Option<Box<Node>> {
101 self.head.map(|node| unsafe {
102 let node = Box::from_raw(node.as_ptr());
103 self.head = node.next;
104 match self.head {
105 Some(head) => (*head.as_ptr()).prev = None,
106 None => self.tail = None,
107 }
108 node
109 })
110 }
111
112 unsafe fn update_node(&mut self, key: &String, offset: Offset) {
113 let (old_v, new_v) = if let Some(&v) = self.keys.get(key) {
114 let new_v = match offset {
115 Offset::Inc => v + 1,
116 Offset::Dec => v - 1,
117 };
118 (self.keys.insert(key.clone(), new_v), new_v)
119 } else {
120 let new_v = match offset {
121 Offset::Inc => 1,
122 Offset::Dec => return,
123 };
124 (self.keys.insert(key.clone(), new_v), new_v)
125 };
126
127 // update index
128 let old_index = if let Some(index) = self.index.get_mut(&new_v) {
129 (*index.as_ptr()).keys.insert(key.clone());
130 old_v.and_then(|old_v| self.index.get_mut(&old_v)).map(|v| *v)
131 } else if new_v > 0 {
132 // insert a new node
133 let mut node = Box::new(Node::default());
134 node.value = new_v;
135 node.keys.insert(key.clone());
136 // find old and attach new node
137 let (old_index, node) = if let Some(old_index) = old_v.and_then(|old_v| self.index.get_mut(&old_v)) {
138 let old_index = old_index.clone();
139 let node = match offset {
140 Offset::Inc => {
141 // insert after
142 node.prev = Some(old_index);
143 node.next = (*old_index.as_ptr()).next.take();
144 let node = Box::leak(node).into();
145 (*old_index.as_ptr()).next = Some(node);
146 (*node.as_ptr()).next.as_mut().map(|n| (*n.as_ptr()).prev = Some(node));
147 node
148 }
149 Offset::Dec => {
150 // insert before
151 node.next = Some(old_index);
152 node.prev = (*old_index.as_ptr()).prev.take();
153 let node = Box::leak(node).into();
154 (*old_index.as_ptr()).prev = Some(node);
155 (*node.as_ptr()).prev.as_mut().map(|n| (*n.as_ptr()).next = Some(node));
156 node
157 }
158 };
159
160 // if new node is tail, update `tail` ptr
161 if (*node.as_ptr()).next.is_none() {
162 self.tail = Some(node);
163 }
164 // if new node is head, update `head` ptr
165 if (*node.as_ptr()).prev.is_none() {
166 self.head = Some(node);
167 }
168 (Some(old_index), node)
169 } else {
170 node.next = self.head;
171 let node = Box::leak(node).into();
172 match self.head {
173 Some(head) => (*head.as_ptr()).prev = Some(node),
174 None => self.tail = Some(node),
175 }
176 self.head = Some(node);
177 (None, node)
178 };
179 self.index.insert(new_v, node);
180 old_index
181 } else {
182 // if new_v == 0, no need to add a new node, but remove instead
183 old_v.and_then(|old_v| self.index.get_mut(&old_v)).map(|v| *v)
184 };
185
186 if let Some(old_index) = old_index {
187 (*old_index.as_ptr()).keys.remove(key);
188 if (*old_index.as_ptr()).keys.is_empty() {
189 // Should drop node
190 let mut node = Box::from_raw(old_index.as_ptr());
191 self.index.remove(&node.value);
192
193 let (mut next, mut prev) = (node.next.take(), node.prev.take());
194 if let Some(ref mut next) = next {
195 (*next.as_ptr()).prev = prev;
196 } else {
197 self.tail = prev;
198 }
199
200 if let Some(ref mut prev) = prev {
201 (*prev.as_ptr()).next = next;
202 } else {
203 // has no prev, update head
204 self.head = next;
205 }
206 }
207 }
208 }
209}
210
211impl Drop for AllOne {
212 /// Must pop every node to drop allocated memory of nodes
213 fn drop(&mut self) {
214 while let Some(node) = self.pop_head() {
215 drop(node);
216 }
217 }
218}
219
220/*
221 * Your AllOne object will be instantiated and called as such:
222 * let obj = AllOne::new();
223 * obj.inc(key);
224 * obj.dec(key);
225 * let ret_3: String = obj.get_max_key();
226 * let ret_4: String = obj.get_min_key();
227 */
228
229#[cfg(test)]
230mod tests {
231 use super::AllOne;
232
233 #[test]
234 fn test() {
235 let mut obj = AllOne::new();
236 // obj.inc("hello".into());
237 // obj.inc("goodbye".into());
238 // obj.inc("hello".into());
239 // obj.inc("hello".into());
240 // let max: String = obj.get_max_key();
241 // let min: String = obj.get_min_key();
242 // println!("\n\nmax: {}, min: {}\n", max, min);
243 //
244 // obj.inc("leet".into());
245 // obj.inc("code".into());
246 // obj.inc("leet".into());
247 // obj.dec("hello".into());
248 // obj.inc("leet".into());
249 // obj.inc("code".into());
250 // obj.inc("code".into());
251 // let max: String = obj.get_max_key();
252 // let min: String = obj.get_min_key();
253 // println!("\n\nmax: {}, min: {}\n", max, min);
254
255 obj.inc("a".into());
256 obj.inc("b".into());
257 obj.inc("b".into());
258 obj.inc("c".into());
259 obj.inc("c".into());
260 obj.inc("c".into());
261 obj.dec("b".into());
262 obj.dec("b".into());
263 let max: String = obj.get_max_key();
264 let min: String = obj.get_min_key();
265 println!("\n\nmax: {}, min: {}\n", max, min);
266
267 obj.dec("a".into());
268
269 let max: String = obj.get_max_key();
270 let min: String = obj.get_min_key();
271 println!("\n\nmax: {}, min: {}\n", max, min);
272 }
273
274 // ["AllOne","inc","inc","inc","inc","getMaxKey","inc","inc","inc","dec","inc","inc","inc","getMaxKey"]
275 // [[],["hello"],["goodbye"],["hello"],["hello"],[],["leet"],["code"],["leet"],["hello"],["leet"],["code"],["code"],[]]
276 //
277 //
278 // inc "hello"
279 // inc "goodbye"
280 // inc "hello"
281 // inc "hello"
282 // getMaxKey
283 // inc "leet"
284 // inc "code"
285 // inc "leet"
286 // dec "hello"
287 // inc "leet"
288 // inc "code"
289 // inc "code"
290 // getMaxKey
291}