• 每天一道Rust-LeetCode(2019-06-14)


    每天一道Rust-LeetCode(2019-06-14) 常数时间插入、删除和获取随机元素

    坚持每天一道题,刷题学习Rust.

    题目描述

    https://leetcode-cn.com/problems/insert-delete-getrandom-o1/
    设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。

    insert(val):当元素 val 不存在时,向集合中插入该项。
    remove(val):元素 val 存在时,从集合中移除该项。
    getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。
    示例 :

    // 初始化一个空的集合。
    RandomizedSet randomSet = new RandomizedSet();

    // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
    randomSet.insert(1);

    // 返回 false ,表示集合中不存在 2 。
    randomSet.remove(2);

    // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
    randomSet.insert(2);

    // getRandom 应随机返回 1 或 2 。
    randomSet.getRandom();

    // 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
    randomSet.remove(1);

    // 2 已在集合中,所以返回 false 。
    randomSet.insert(2);

    // 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
    randomSet.getRandom();

    解题过程

    思路:1.用slice存值,用map保存值在slice中的index;
    2.每次删除时,为了避免移动元素,用数组末尾元素覆盖需要删除的元素,然后删除数组末尾元素;

    extern crate rand;
    use rand::Rng;
    use std::collections::HashMap;
    use std::collections::HashSet;
    struct RandomizedSet {
        m: HashMap<i32, usize>,
        v: Vec<i32>,
    }
    
    /**
     * `&self` means the method takes an immutable reference.
     * If you need a mutable reference, change it to `&mut self` instead.
     */
    impl RandomizedSet {
        /** Initialize your data structure here. */
        fn new() -> Self {
            RandomizedSet {
                m: HashMap::new(),
                v: Vec::new(),
            }
        }
    
        /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
        pub fn insert(&mut self, val: i32) -> bool {
            if self.m.contains_key(&val) {
                return false;
            }
            let i = self.m.len();
            if self.v.len() > i {
                //经过删除以后v里面空间可能非常富裕,直接用现有的才对
                self.v[i] = val;
            } else {
                self.v.push(val);
            }
            self.m.insert(val, i);
            return true;
        }
    
        /** Removes a value from the set. Returns true if the set contained the specified element. */
        pub fn remove(&mut self, val: i32) -> bool {
            if !self.m.contains_key(&val) {
                return false;
            }
            let i = *self.m.get(&val).expect("must ok");
            if i != self.m.len() - 1 {
                //如果是最后一个,就不用调整了
                self.v[i] = self.v[self.m.len() - 1]; //最后一个值填充到i
                self.m.insert(self.v[i], i);
            }
            self.m.remove(&val);
            return true;
        }
    
        /** Get a random element from the set. */
        pub fn get_random(&self) -> i32 {
            let mut rng = rand::thread_rng();
            let mut i: usize = rng.gen();
            i = i % self.m.len();
            return self.v[i];
        }
    }
    

    一点感悟

    rust标准库中居然没有随机数生成器.

    其他

    欢迎关注我的github,本项目文章所有代码都可以找到.

  • 相关阅读:
    适用于小内存MCU的开源加密算法库(转)
    EventOS 超级轻量、事件驱动型嵌入式开发框架(转)
    WiFi网卡(RTL8723)驱动移植(转)
    10分钟教你搭建一个嵌入式web服务器(转)
    C# 给Word每一页设置不同文字水印 E
    Java 插入公式到PPT幻灯片 E
    Java 加载、编辑和保存WPS表格文件(.et/.ett) E
    Java 将Excel转为UOS E
    Spire.Cloud 私有化部署教程(三) Windows 系统 E
    Java 自定义Excel数据排序 E
  • 原文地址:https://www.cnblogs.com/baizx/p/11020730.html
Copyright © 2020-2023  润新知