LeetCode 0677
About 2 min
0677. Map Sum Pairs
- Tags: Thiết kế, Cây tiền tố, Bảng băm, Chuỗi
- Độ khó: Trung bình
Tóm tắt đề bài
Yêu cầu: Triển khai lớp MapSum, hỗ trợ hai phương thức insert
và sum
:
MapSum()
Khởi tạo đối tượng MapSum.void insert(String key, int val)
Chèn cặp khóakey-val
vào, trong đó chuỗikey
đại diện cho khóa và số nguyênval
đại diện cho giá trị. Nếu khóakey
đã tồn tại, cặp khóa giá trị cũ sẽ bị thay thế bằng cặp khóa giá trị mới.int sum(string prefix)
Trả về tổng giá trị của tất cả các khóakey
bắt đầu bằng tiền tốprefix
.
Giải thích:
- .
key
vàprefix
chỉ chứa các ký tự chữ cái thường.- .
- Gọi hàm
insert
vàsum
tối đa lần.
Ví dụ:
- Ví dụ 1:
Input:
["MapSum", "insert", "sum", "insert", "sum"]
[[], ["apple", 3], ["ap"], ["app", 2], ["ap"]]
Output:
[null, null, 3, null, 5]
Giải thích:
MapSum mapSum = new MapSum();
mapSum.insert("apple", 3);
mapSum.sum("ap"); // Trả về 3 (apple = 3)
mapSum.insert("app", 2);
mapSum.sum("ap"); // Trả về 5 (apple + app = 3 + 2 = 5)
Ý tưởng giải quyết
Ý tưởng 1: Cây tiền tố (Trie)
Chúng ta có thể xây dựng một cây tiền tố (Trie) để giải quyết bài toán.
- Trong quá trình khởi tạo, chúng ta xây dựng một cây tiền tố (Trie) và thêm biến
value
. - Khi gọi phương thức chèn, chúng ta lưu trữ
key
trong cây tiền tố và lưu trữvalue
tương ứng trong nút chữ cái tương ứng. - Khi gọi phương thức tính tổng, chúng ta trước tiên tìm kiếm nút cây tiền tố tương ứng với tiền tố
prefix
, bắt đầu từ nút đó, chúng ta duyệt qua các nút con và tính tổng cácvalue
của các nút con, sau đó trả về tổng tích lũy.
Ý tưởng 1: Đoạn mã
class Node:
def __init__(self):
self.children = {}
self.isEnd = False
self.value = 0
class Trie:
def __init__(self):
self.root = Node()
def insert(self, key, val):
cur = self.root
for ch in key:
if ch not in cur.children:
cur.children[ch] = Node()
cur = cur.children[ch]
cur.isEnd = True
cur.value = val
def search(self, prefix):
cur = self.root
for ch in prefix:
if ch not in cur.children:
return 0
cur = cur.children[ch]
return self.dfs(cur)
def dfs(self, root):
if not root:
return 0
res = root.value
for node in root.children.values():
res += self.dfs(node)
return res
class MapSum:
def __init__(self):
self.trie = Trie()
def insert(self, key: str, val: int) -> None:
self.trie.insert(key, val)
def sum(self, prefix: str) -> int:
return self.trie.search(prefix)
Ý tưởng 1: Độ phức tạp
- Độ phức tạp thời gian: Phương thức
insert
có độ phức tạp thời gian là , trong đó là độ dài của chuỗikey
. Phương thứcsum
có độ phức tạp thời gian là , trong đó là độ dài của chuỗiprefix
. - Độ phức tạp không gian: . Trong đó là độ dài lớn nhất của chuỗi
key
, là số lượng cặp khóa-giá trịkey-val
.