[Leetcode] 1146. Snapshot Array (Medium)

概述

題目

https://leetcode.com/problems/snapshot-array/
設計一個類似 NAS 的快照系統,init 功能為初始化,給予一 length 長度表需要的空間;set 為設定某空間的數值;snap 表於該時間點快照一張,注意:可都不改變空間資料但要求快照;get 表給予某一次快照時間,並回傳該快照時間之某空間資料為何

心得

題目有點難看懂,但理解後應可體會是道很經典、優秀的題目,實務上也有很高機率會需要建構此種系統,為加速快照搜詢,以 Binary Search 解之

Binary Search

思路

基本資料的建立都如題意所述,維 get 時加入 Binary Search 的操作以增加效率

程式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class SnapshotArray(object):

def __init__(self, length):
"""
:type length: int
"""
self.arr = [[[0, 0]] for i in range(length)]
self.len = length
self.cnt = 0

def set(self, index, val):
"""
:type index: int
:type val: int
:rtype: None
"""
self.arr[index].append([self.cnt, val])

def snap(self):
"""
:rtype: int
"""
self.cnt += 1
return self.cnt-1

def get(self, index, snap_id):
"""
:type index: int
:type snap_id: int
:rtype: int
"""
arr = self.arr[index]
n = len(arr)
l, r = 0, n

# Binary Search
def test(m):
return arr[m][0] <= snap_id

while l<r:
m = (l+r)//2
if test(m-1) and not test(m):
return arr[m-1][1]
if not test(m):
r = m
else:
l = m+1
return arr[l-1][1]


# Your SnapshotArray object will be instantiated and called as such:
# obj = SnapshotArray(length)
# obj.set(index,val)
# param_2 = obj.snap()
# param_3 = obj.get(index,snap_id)

Complexity

Time Complexity: O(n log(n))
建構資料庫需 O(n) 的時間,搜詢只需 O(log n),有可能有 n 次 get 操作,故 O(n log(n))

Space Complexity: O(n)
n 次操作佔 n 個空間位置

PS.Solution 中有不少雙層 Hash 的解法,後經實測皆會有 MLE 的狀況,故基本上都無法 AC