Skip to content

Commit 04d8d6e

Browse files
committed
feat: 0981.Time-Based-Key-Value-Store
1 parent a0d7284 commit 04d8d6e

File tree

5 files changed

+341
-0
lines changed

5 files changed

+341
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
title: 0981.Time Based Key-Value Store
3+
subtitle: "https://leetcode.com/problems/time-based-key-value-store/description/"
4+
date: 2024-01-22T21:20:00+08:00
5+
lastmod: 2024-01-22T21:20:00+08:00
6+
draft: false
7+
author: "Kimi.Tsai"
8+
authorLink: "https://kimi0230.github.io/"
9+
description: "0981.Time-Based-Key-Value-Store"
10+
license: ""
11+
images: []
12+
13+
tags: [LeetCode, Go, Medium, Time Based Key-Value Store, Hash Table, String, Binary Search, Design]
14+
categories: [LeetCode]
15+
16+
featuredImage: ""
17+
featuredImagePreview: ""
18+
19+
hiddenFromHomePage: false
20+
hiddenFromSearch: false
21+
twemoji: false
22+
lightgallery: true
23+
ruby: true
24+
fraction: true
25+
fontawesome: true
26+
linkToMarkdown: false
27+
rssFullText: false
28+
29+
toc:
30+
enable: true
31+
auto: true
32+
code:
33+
copy: true
34+
maxShownLines: 200
35+
math:
36+
enable: false
37+
# ...
38+
mapbox:
39+
# ...
40+
share:
41+
enable: true
42+
# ...
43+
comment:
44+
enable: true
45+
# ...
46+
library:
47+
css:
48+
# someCSS = "some.css"
49+
# located in "assets/"
50+
# Or
51+
# someCSS = "https://cdn.example.com/some.css"
52+
js:
53+
# someJS = "some.js"
54+
# located in "assets/"
55+
# Or
56+
# someJS = "https://cdn.example.com/some.js"
57+
seo:
58+
images: []
59+
# ...
60+
---
61+
# [0981.Time Based Key-Value Store](https://leetcode.com/problems/time-based-key-value-store/description/)
62+
63+
## 題目
64+
65+
## 題目大意
66+
67+
68+
## 解題思路
69+
70+
## Big O
71+
72+
* 時間複雜 : ``
73+
* 空間複雜 : ``
74+
75+
## 來源
76+
* https://leetcode.com/problems/time-based-key-value-store/description/
77+
* https://leetcode.cn/problems/
78+
79+
## 解答
80+
https://github.com/kimi0230/LeetcodeGolang/blob/master/Leetcode/0981.Time-Based-Key-Value-Store/main.go
81+
82+
```go
83+
package timebasedkeyvaluestore
84+
85+
import "sort"
86+
87+
// 時間複雜 O(), 空間複雜 O()
88+
type element struct {
89+
key string
90+
value string
91+
timestamp int
92+
}
93+
94+
type TimeMap struct {
95+
elements map[string][]element
96+
}
97+
98+
func Constructor() TimeMap {
99+
return TimeMap{elements: make(map[string][]element)}
100+
}
101+
102+
func (this *TimeMap) Set(key string, value string, timestamp int) {
103+
this.elements[key] = append(this.elements[key], element{
104+
key: key,
105+
value: value,
106+
timestamp: timestamp,
107+
})
108+
}
109+
110+
// O(log n)
111+
func (this *TimeMap) Get(key string, timestamp int) string {
112+
if _, ok := this.elements[key]; !ok {
113+
return ""
114+
}
115+
// 二分法找出符合條件的最左邊
116+
index := sort.Search(len(this.elements[key]), func(i int) bool {
117+
return this.elements[key][i].timestamp > timestamp
118+
})
119+
if index == 0 {
120+
return ""
121+
}
122+
123+
index--
124+
return this.elements[key][index].value
125+
}
126+
127+
```
128+
129+
## Benchmark
130+
131+
```sh
132+
133+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package timebasedkeyvaluestore
2+
3+
import "sort"
4+
5+
// 時間複雜 O(), 空間複雜 O()
6+
type element struct {
7+
key string
8+
value string
9+
timestamp int
10+
}
11+
12+
type TimeMap struct {
13+
elements map[string][]element
14+
}
15+
16+
func Constructor() TimeMap {
17+
return TimeMap{elements: make(map[string][]element)}
18+
}
19+
20+
func (this *TimeMap) Set(key string, value string, timestamp int) {
21+
this.elements[key] = append(this.elements[key], element{
22+
key: key,
23+
value: value,
24+
timestamp: timestamp,
25+
})
26+
}
27+
28+
// O(log n)
29+
func (this *TimeMap) Get(key string, timestamp int) string {
30+
if _, ok := this.elements[key]; !ok {
31+
return ""
32+
}
33+
// 二分法找出符合條件的最左邊
34+
index := sort.Search(len(this.elements[key]), func(i int) bool {
35+
return this.elements[key][i].timestamp > timestamp
36+
})
37+
if index == 0 {
38+
return ""
39+
}
40+
41+
index--
42+
return this.elements[key][index].value
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package timebasedkeyvaluestore
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestTimeMap(t *testing.T) {
8+
timeMap := Constructor()
9+
timeMap.Set("foo", "bar", 1)
10+
timeMap.Set("foo", "bar2", 4)
11+
timeMap.Set("foo", "bar3", 6)
12+
13+
tests := []struct {
14+
key string
15+
timestamp int
16+
want string
17+
}{
18+
{"foo", 1, "bar"},
19+
{"foo", 3, "bar"},
20+
{"foo", 4, "bar2"},
21+
{"foo", 5, "bar2"},
22+
{"foo", 6, "bar3"},
23+
{"foo", 7, "bar3"},
24+
{"foo2", 1, ""},
25+
}
26+
27+
for _, tt := range tests {
28+
got := timeMap.Get(tt.key, tt.timestamp)
29+
if got != tt.want {
30+
t.Errorf("Get(%v, %v) = %v, want %v", tt.key, tt.timestamp, got, tt.want)
31+
}
32+
}
33+
}
34+
35+
func BenchmarkTimeMap_Get(b *testing.B) {
36+
timeMap := Constructor()
37+
timeMap.Set("foo", "bar", 1)
38+
timeMap.Set("foo", "bar2", 4)
39+
timeMap.Set("foo", "bar3", 6)
40+
41+
b.ResetTimer()
42+
for i := 0; i < b.N; i++ {
43+
timeMap.Get("foo", 5)
44+
}
45+
}
46+
47+
/*
48+
go test -benchmem -run=none LeetcodeGolang/Leetcode/0354.Russian-Doll-Envelopes -bench=.
49+
50+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// 時間複雜度:
2+
// 空間複雜度:
3+
/*
4+
* @lc app=leetcode.cn id=981 lang=golang
5+
*
6+
* [981] 基于时间的键值存储
7+
*
8+
* https://leetcode.cn/problems/time-based-key-value-store/description/
9+
*
10+
* algorithms
11+
* Medium (52.55%)
12+
* Likes: 226
13+
* Dislikes: 0
14+
* Total Accepted: 32.9K
15+
* Total Submissions: 62.7K
16+
* Testcase Example: '["TimeMap","set","get","get","set","get","get"]\n' +
17+
'[[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]]'
18+
*
19+
* 设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。
20+
*
21+
* 实现 TimeMap 类:
22+
*
23+
*
24+
* TimeMap() 初始化数据结构对象
25+
* void set(String key, String value, int timestamp) 存储给定时间戳 timestamp 时的键 key
26+
* 和值 value。
27+
* String get(String key, int timestamp) 返回一个值,该值在之前调用了 set,其中 timestamp_prev
28+
* <= timestamp 。如果有多个这样的值,它将返回与最大  timestamp_prev 关联的值。如果没有值,则返回空字符串("")。
29+
*
30+
*
31+
*
32+
* 示例 1:
33+
*
34+
*
35+
* 输入:
36+
* ["TimeMap", "set", "get", "get", "set", "get", "get"]
37+
* [[], ["foo", "bar", 1], ["foo", 1], ["foo", 3], ["foo", "bar2", 4], ["foo",
38+
* 4], ["foo", 5]]
39+
* 输出:
40+
* [null, null, "bar", "bar", null, "bar2", "bar2"]
41+
*
42+
* 解释:
43+
* TimeMap timeMap = new TimeMap();
44+
* timeMap.set("foo", "bar", 1); // 存储键 "foo" 和值 "bar" ,时间戳 timestamp = 1
45+
* timeMap.get("foo", 1); // 返回 "bar"
46+
* timeMap.get("foo", 3); // 返回 "bar", 因为在时间戳 3 和时间戳 2 处没有对应 "foo"
47+
* 的值,所以唯一的值位于时间戳 1 处(即 "bar") 。
48+
* timeMap.set("foo", "bar2", 4); // 存储键 "foo" 和值 "bar2" ,时间戳 timestamp = 4
49+
* timeMap.get("foo", 4); // 返回 "bar2"
50+
* timeMap.get("foo", 5); // 返回 "bar2"
51+
*
52+
*
53+
*
54+
*
55+
* 提示:
56+
*
57+
*
58+
* 1 <= key.length, value.length <= 100
59+
* key 和 value 由小写英文字母和数字组成
60+
* 1 <= timestamp <= 10^7
61+
* set 操作中的时间戳 timestamp 都是严格递增的
62+
* 最多调用 set 和 get 操作 2 * 10^5 次
63+
*
64+
*
65+
*/
66+
67+
// @lc code=start
68+
69+
type element struct {
70+
key string
71+
value string
72+
timestamp int
73+
}
74+
75+
type TimeMap struct {
76+
elements map[string][]element
77+
}
78+
79+
func Constructor() TimeMap {
80+
return TimeMap{elements: make(map[string][]element)}
81+
}
82+
83+
func (this *TimeMap) Set(key string, value string, timestamp int) {
84+
this.elements[key] = append(this.elements[key], element{
85+
key: key,
86+
value: value,
87+
timestamp: timestamp,
88+
})
89+
}
90+
91+
func (this *TimeMap) Get(key string, timestamp int) string {
92+
if _, ok := this.elements[key]; !ok {
93+
return ""
94+
}
95+
// 二分法找出符合條件的最左邊
96+
index := sort.Search(len(this.elements[key]), func(i int) bool {
97+
return this.elements[key][i].timestamp > timestamp
98+
})
99+
if index == 0 {
100+
return ""
101+
}
102+
103+
index--
104+
return this.elements[key][index].value
105+
}
106+
107+
/**
108+
* Your TimeMap object will be instantiated and called as such:
109+
* obj := Constructor();
110+
* obj.Set(key,value,timestamp);
111+
* param_2 := obj.Get(key,timestamp);
112+
*/
113+
// @lc code=end
114+

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ func search(nums []int, target int) int {
524524
| [0153](https://kimi0230.github.io/LeetcodeGolang/Leetcode/0153.Find-Minimum-in-Rotated-Sorted-Array/) | [153. Find Minimum in Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0153.Find-Minimum-in-Rotated-Sorted-Array) | Medium | O(log n) | O(1) | Binary Search |
525525
| [0033](https://kimi0230.github.io/LeetcodeGolang/Leetcode/0033.Search-in-Rotated-Sorted-Array/) | [33. Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/description//) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0033.Search-in-Rotated-Sorted-Array) | Medium | O(log n) | O(1) | Binary Search |
526526
| [0034](https://kimi0230.github.io/LeetcodeGolang/Leetcode/0034.Find-First-and-Last-Position-of-Element-in-Sorted-Array/) | [34. Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0034.Find-First-and-Last-Position-of-Element-in-Sorted-Array) | Medium | O(log n) | O(1) | Binary Search |
527+
| [0981](https://kimi0230.github.io/LeetcodeGolang/Leetcode/0981.Time-Based-Key-Value-Store/) | [0981.Time Based Key-Value Store](https://leetcode.com/problems/time-based-key-value-store/description/) | [Go](https://github.com/kimi0230/LeetcodeGolang/tree/master/Leetcode/0981.Time-Based-Key-Value-Store) | Medium | O(log n) | | Binary Search |
527528
528529
529530
---

0 commit comments

Comments
 (0)