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}