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


题目地址:https://leetcode.com/problems/time-based-key-value-store/

题目描述

Create a timebased key-value store class TimeMap, that supports two operations.

  1. set(string key, string value, int timestamp)
  • Stores the key and value, along with the given timestamp.
  1. get(string key, int timestamp)
  • Returns a value such that set(key, value, timestamp_prev) was called previously, with timestamp_prev <= timestamp.
  • If there are multiple such values, it returns the one with the largest timestamp_prev.
  • If there are no values, it returns the empty string ("").

Example 1:

Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]]
Output: [null,null,"bar","bar",null,"bar2","bar2"]
Explanation:
TimeMap kv;
kv.set("foo", "bar", 1); // store the key "foo" and value "bar" along with timestamp = 1
kv.get("foo", 1); // output "bar"
kv.get("foo", 3); // output "bar" since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 ie "bar"
kv.set("foo", "bar2", 4);
kv.get("foo", 4); // output "bar2"
kv.get("foo", 5); //output "bar2"

Example 2:

Input: inputs = ["TimeMap","set","set","get","get","get","get","get"], inputs = [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["love",20],["love",25]]
Output: [null,null,null,"","high","high","low","low"]

Note:

  1. All key/value strings are lowercase.
  2. All key/value strings have length in the range [1, 100]
  3. The timestamps for all TimeMap.set operations are strictly increasing.
  4. 1 <= timestamp <= 10^7
  5. TimeMap.set and TimeMap.get functions will be called a total of 120000 times (combined) per test case.

题目大意

构建一个带有时间版本的KV存储器。即每次保存的时候会保存当前的时间,查询的时候给出一个时间,要求找到先于该时间的最新的key对应的value。

解题方法

字典

没想到LC还会出这么新颖的题目,这个应用场景在数据库设计中确实会用到。

首先分析一下,我们应该怎么办。首先,如果给出了任意的时间,我们都要找出先于这个时间的key对应的value,说明我们必须把每次的插入结果与对应的时间都保存,而不能使用覆盖的方式。

很显然我们会使用字典这种数据结构来存储kv对,为了保存每个key插入的时间,而且要保证最快的查询时间,我分开保存每次插入的key的time和value。为什么这么做有效呢?因为如果我如果使用key : [(time1, value1), (time2, value2)...]这种存储方式,对快速查找是不利的。而使用key : [time1, time2...]key : [value1, value2...]这种存储方式能保证time和value是一一对应的。所以这种方式先根据key和time快速查找到小于该时间的timex,然后就能根据索引快速找到此索引对应的valuex.

在有序列表中快速查找小于一个time的time_x,当然使用二分了,所以使用了bisect_right来快速查找到了一个不大于该time的时间对应的索引,然后拿这个索引找到对应的value即可。

万万没想到的是,竟然没通过!我已经优化了存储和查找啊!看了下没通过的测试用例,发现是一个键值对反复的插入查找,每次查找的时间都是最新的时间。好吧,那么我使用了一个这个max_字典,用来保存当前的key更新的时间。这样的好处是,当我们查找一个不小于当前时间的值的时候,一定是最后一次插入的那个时间。

最后,说句题外话,这个题没有考到的是我们的删除操作怎么办?其实业界做法是使用延迟删除的方式,即插入一个标志位代表删除,而不进行真正的删除操作。比如我们在最后的时刻设置key为"",这样我们查找的时候发现这个key的数值是""就意味着被删除。

class TimeMap(object):

    def __init__(self):
"""
Initialize your data structure here.
"""
self.t_ = collections.defaultdict(list)
self.v_ = collections.defaultdict(list)
self.max_ = collections.defaultdict(int) def set(self, key, value, timestamp):
"""
:type key: str
:type value: str
:type timestamp: int
:rtype: None
"""
self.t_[key].append(timestamp)
self.v_[key].append(value)
self.max_[key] = max(self.max_[key], timestamp) def get(self, key, timestamp):
"""
:type key: str
:type timestamp: int
:rtype: str
"""
if key not in self.t_:
return ""
if timestamp >= self.max_[key]:
return self.v_[key][-1]
v = bisect.bisect_right(self.t_[key], timestamp)
if v:
return self.v_[key][v - 1]
return "" # Your TimeMap object will be instantiated and called as such:
# obj = TimeMap()
# obj.set(key,value,timestamp)
# param_2 = obj.get(key,timestamp)

日期

2019 年 1 月 27 日 —— 这个周赛不太爽

【LeetCode】981. Time Based Key-Value Store 解题报告(Python)的更多相关文章

  1. 【LeetCode】94. Binary Tree Inorder Traversal 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 递归 迭代 日期 题目地址:https://leetcode.c ...

  2. 【LeetCode】341. Flatten Nested List Iterator 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归+队列 栈 日期 题目地址:https://lee ...

  3. 【LeetCode】589. N-ary Tree Preorder Traversal 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leetc ...

  4. 【LeetCode】92. Reverse Linked List II 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 递归 日期 题目地址:https://leet ...

  5. Leetcode 981. Time Based Key-Value Store(二分查找)

    题目来源:https://leetcode.com/problems/time-based-key-value-store/description/ 标记难度:Medium 提交次数:1/1 代码效率 ...

  6. 【LeetCode】449. Serialize and Deserialize BST 解题报告(Python)

    [LeetCode]449. Serialize and Deserialize BST 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/pro ...

  7. 【LeetCode】692. Top K Frequent Words 解题报告(Python)

    [LeetCode]692. Top K Frequent Words 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/top ...

  8. 【LeetCode】697. Degree of an Array 解题报告

    [LeetCode]697. Degree of an Array 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/degree- ...

  9. 【LeetCode】779. K-th Symbol in Grammar 解题报告(Python)

    [LeetCode]779. K-th Symbol in Grammar 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingz ...

  10. 【LeetCode】792. Number of Matching Subsequences 解题报告(Python)

    [LeetCode]792. Number of Matching Subsequences 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

随机推荐

  1. jmeter非GUI(cmd命令行)模式的压测和输出测试报告

    1.非GUI模式的压测,和GUI有啥不同? 2.非GUI模式怎么搞? 大家打开jmeter的时候,都会看到这个界面: 注意看这句话: Don't use GUI mode for load testi ...

  2. c++ cmake及包管理工具conan简单入门

    cmake是一个跨平台的c/c++工程管理工具,可以通过cmake轻松管理我们的项目 conan是一个包管理工具,能够自动帮助我们下载及管理依赖,可以配合cmake使用 这是一个入门教程,想深入了解的 ...

  3. hashtable深度探索

    1.什么是哈希表(hashtable)?为什么要发明哈希表? 首先回答第二个问题,在之前的数据结构中我们学习了数组,链表,二叉树等数据结构,记录在结构中的相对位置是随机的,和记录的关键字之前不存在确定 ...

  4. Spring Batch : 在不同steps间传递数据

    参考文档: How can we share data between the different steps of a Job in Spring Batch? Job Scoped Beans i ...

  5. java中二维数组初始化的几种方法

    /* 第一种方式 */ int tdarr1[][] = { { 1, 3, 5 }, { 5, 9, 10 } }; /* 第二种方式 */ int tdarr2[][] = new int[][] ...

  6. 莫烦python教程学习笔记——使用鸢尾花数据集

    # View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...

  7. shell脚本 微信/钉钉验证登录服务器

    一.简介 登录用户需要二次验证码进行验证 可以配合 监控用户登录,发送通知给企业微信/钉钉 来使用 脚本放到/etc/profile.d/ 目录,登录的时候自动触发 二.微信脚本 1.需要修改Crop ...

  8. 配置文件管理维护到gitlab上

    一.简介 在日常维护服务器中,会修改配置文件或者相应脚本,在修改前要对文件进行按照日期备份,这样会很麻烦,频繁修改的时候也会懒得去备份多个. 维护脚本分为服务端和客户端,服务端监听端口,接收客户端的采 ...

  9. [IDEA] chapter_reader - idea看小说插件 idea阅读插件 idea摸鱼插件

    目录 1. 简述: 2. 使用说明: 2.1 版本说明: 2.2 重要说明: 2.3 简单使用方法: 2.4 目前支持的网站有 (新↓): 2.5 菜单介绍: 2.6 快捷键设置及推荐: 2.7 在线 ...

  10. 车载以太网第二弹|测试之实锤 -DoIP测试开发实践

    前言 车载以太网测试之实锤系列,之前我们已经从环境设备组成.被测对象组成再到测试过程和测试结果分析,分享了完整的PMA测试 .IOP测试 .TC8中的TCP/IP协议一致性测试 .也分享了1000BA ...