【LeetCode】380. Insert Delete GetRandom O(1) 解题报告(Python)

作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/insert-delete-getrandom-o1/description/

题目描述:

Design a data structure that supports all following operations in average O(1) time.

  1. insert(val): Inserts an item val to the set if not already present.
  2. remove(val): Removes an item val from the set if present.
  3. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

Example:

// Init an empty set.
RandomizedSet randomSet = new RandomizedSet(); // Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomSet.insert(1); // Returns false as 2 does not exist in the set.
randomSet.remove(2); // Inserts 2 to the set, returns true. Set now contains [1,2].
randomSet.insert(2); // getRandom should return either 1 or 2 randomly.
randomSet.getRandom(); // Removes 1 from the set, returns true. Set now contains [2].
randomSet.remove(1); // 2 was already in the set, so return false.
randomSet.insert(2); // Since 2 is the only number in the set, getRandom always return 2.
randomSet.getRandom();

题目大意

设计一个数据结构,有三个方法:插入、删除、随机选取一个数值。要求平均的时间复杂度是O(1).

解题方法

插入删除的时间复杂度要求O(1)的话,很容易想起来是set。所以我就用set来实现了。但是随机选取的时候,由于set不能使用索引,所以我先把它转成了list,然后使用随机数来进行索引。不知道python中set转list的时间复杂度是多少,估计最坏情况应该是O(n),这一步没有满足题目的要求,但是也过了。

这个题目没有说清楚如果数据结构为空的时候使用getRandom()应该怎么返回,我觉得是个bug。当然测试用例避开了这一点。

代码如下:

class RandomizedSet(object):

    def __init__(self):
"""
Initialize your data structure here.
"""
self.set = set()
self.size = 0 def insert(self, val):
"""
Inserts a value to the set. Returns true if the set did not already contain the specified element.
:type val: int
:rtype: bool
"""
if val not in self.set:
self.set.add(val)
self.size += 1
return True
return False def remove(self, val):
"""
Removes a value from the set. Returns true if the set contained the specified element.
:type val: int
:rtype: bool
"""
if val in self.set:
self.set.remove(val)
self.size -= 1
return True
return False def getRandom(self):
"""
Get a random element from the set.
:rtype: int
"""
ind = random.randint(0, self.size - 1)
return list(self.set)[ind] # Your RandomizedSet object will be instantiated and called as such:
# obj = RandomizedSet()
# param_1 = obj.insert(val)
# param_2 = obj.remove(val)
# param_3 = obj.getRandom()

参考了一下,发现可以使用字典保存每个元素出现的位置,那么和list结合之后,每次移除一个元素的方式是把list结尾元素对要被移除元素出现的位置进行原地替换,这样就能把时间复杂度降下来。

如果list删除某个位置的元素,那么时间复杂度是O(N),但是如果用最后的元素对该位置进行替换,并且移除最后的元素,时间复杂度能降到O(1)。

特别注意骚操作都在remove里面的,注意位置替换,以及别忘记把list和dict中要移除的元素删除。

class RandomizedSet(object):

    def __init__(self):
"""
Initialize your data structure here.
"""
self.nums, self.pos = list(), dict() def insert(self, val):
"""
Inserts a value to the set. Returns true if the set did not already contain the specified element.
:type val: int
:rtype: bool
"""
if val not in self.pos:
self.nums.append(val)
self.pos[val] = len(self.nums) - 1
return True
return False def remove(self, val):
"""
Removes a value from the set. Returns true if the set contained the specified element.
:type val: int
:rtype: bool
"""
if val in self.pos:
idx, last = self.pos[val], self.nums[-1]
self.nums[idx] = last
self.pos[last] = idx
self.nums.pop()
self.pos.pop(val, 0)
return True
return False def getRandom(self):
"""
Get a random element from the set.
:rtype: int
"""
idx = random.randint(0, len(self.nums) - 1)
return self.nums[idx] # Your RandomizedSet object will be instantiated and called as such:
# obj = RandomizedSet()
# param_1 = obj.insert(val)
# param_2 = obj.remove(val)
# param_3 = obj.getRandom()

参考资料:

https://leetcode.com/problems/insert-delete-getrandom-o1/discuss/85397/Simple-solution-in-Python

日期

2018 年 9 月 17 日 —— 早上很凉,夜里更凉

【LeetCode】380. Insert Delete GetRandom O(1) 解题报告(Python)的更多相关文章

  1. LeetCode 380. Insert Delete GetRandom O(1)

    380. Insert Delete GetRandom O(1) Add to List Description Submission Solutions Total Accepted: 21771 ...

  2. [LeetCode] 380. Insert Delete GetRandom O(1) 插入删除获得随机数O(1)时间

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  3. leetcode 380. Insert Delete GetRandom O(1) 、381. Insert Delete GetRandom O(1) - Duplicates allowed

    380. Insert Delete GetRandom O(1) 实现插入.删除.获得随机数功能,且时间复杂度都在O(1).实际上在插入.删除两个功能中都包含了查找功能,当然查找也必须是O(1). ...

  4. [LeetCode] 380. Insert Delete GetRandom O(1) 常数时间内插入删除和获得随机数

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  5. LeetCode 380. Insert Delete GetRandom O(1) (插入删除和获得随机数 常数时间)

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  6. [leetcode]380. Insert Delete GetRandom O(1)常数时间插入删除取随机值

    Design a data structure that supports all following operations in average O(1) time. insert(val): In ...

  7. LeetCode 380. Insert Delete GetRandom O(1) 常数时间插入、删除和获取随机元素(C++/Java)

    题目: Design a data structure that supports all following operations in averageO(1) time. insert(val): ...

  8. [leetcode]380. Insert Delete GetRandom O(1)设计数据结构,实现存,删,随机取的时间复杂度为O(1)

    题目: Design a data structure that supports all following operations in average O(1) time.1.insert(val ...

  9. [LeetCode] 381. Insert Delete GetRandom O(1) - Duplicates allowed 插入删除和获得随机数O(1)时间 - 允许重复

    Design a data structure that supports all following operations in average O(1) time. Note: Duplicate ...

随机推荐

  1. Excel—分组然后取每组中对应时间列值最大的或者最小的

    1.MAX(IF(A:A=D2,B:B)) 输入函数公式后,按Ctrl+Shift+Enter键使函数公式成为数组函数公式. Ctrl+Shift+Enter: 按住Ctrl键不放,继续按Shift键 ...

  2. EXCEL-时间

    1.时间的3中输入方法: (1)手打输入: (2)快捷键:[快,方便,且结果跟手打一样,不会改变][Ctrl+;]->年月日    [Ctrl+:]->时分秒(我这里是这样的效果) (3) ...

  3. ubuntu终端ls颜色配置

    buntu中没有LS_COLORS,/etc/目录中也没有DIR_COLORS,所以这里使用dircolor命令加以解决 1. 利用dircolors命令,查看我们的系统当前的文件名称显示颜色的值,然 ...

  4. Redis集合解决大数据筛选

    Redis集合:集合是什么,就是一堆确定的数据放在一起,数学上集合有交集.并集的概念,这个就可以用来做大数据的筛选功能. 以商品为例,假如商品有颜色和分类.价格区间等属性. 给所有统一颜色的商品放一个 ...

  5. Angular @Input讲解及用法

    1.什么是@input @input的作用是定义模块输入,是用来让父级组件向子组件传递内容. 2.@input用法 首先在子组件中将需要传递给父组件的变量用@input()修饰 需要在子组件ts文件i ...

  6. 100个Shell脚本——【脚本3】tomcat启动脚本

    [脚本3]tomcat启动脚本 一.脚本tomcatd.sh #!/bin/bash # chkconfig:2345 64 36 # description: Tomcat start/stop/r ...

  7. MapStruct对象转换

    第一次看到 MapStruct 的时候, 我个人非常的开心.因为其跟我内心里面的想法不谋而合. 1 MapStruct 是什么? 1.1 JavaBean 的困扰 对于代码中 JavaBean之间的转 ...

  8. Linux学习 - 正则表达式

    一.正则表达式与通配符 正则表达式:在文件中匹配符合条件的字符串,正则是包含匹配 通配符:用来匹配符合条件的文件名,通配符是完全匹配 二.基础正则表达式 元字符 作用 a* a有0个或任意多个 . 除 ...

  9. 【编程思想】【设计模式】【行为模式Behavioral】catalog

    Python版 https://github.com/faif/python-patterns/blob/master/behavioral/catalog.py #!/usr/bin/env pyt ...

  10. 【Linux】【Basis】CentOS启动流程

    1. 基础概念       1.1 Linux系统的组成部分:内核+根文件系统         内核:进程管理.内存管理.网络协议栈.文件系统.驱动程序.安全功能             IPC:In ...