设计自定义结构意味着组合现有结构,使得每个所需操作都能达到其目标复杂度,让一个结构弥补另一个结构的弱点。经典的技术是将哈希表与数组、堆或链表配对。
一个实际例子:insert、delete、getRandom — 全部 O(1)
要求:、 和 都在 O(1) 时间内完成。单独的哈希表无法做到 O(1) 随机访问;单独的数组无法做到 O(1) 删除。。
insert(x)remove(x)getRandom()import random
class RandomizedSet:
def __init__(self):
self.idx = {} # value -> index in list
self.vals = [] # values for O(1) random pick
def insert(self, x): # O(1)
if x in self.idx: return False
self.idx[x] = len(self.vals)
self.vals.append(x)
return True
def remove(self, x): # O(1): swap with last, pop
if x not in self.idx: return False
i, last = self.idx[x], self.vals[-1]
self.vals[i] = last # move last into the hole
self.idx[last] = i
self.vals.pop()
del self.idx[x]
return True
def getRandom(self): # O(1)
return random.choice(self.vals)
1. List every required operation + its target complexity.
2. For each, name a structure that hits it:
by key O(1) -> hash map
by index O(1) -> array
min/max O(log n) -> heap
ordered O(log n) -> balanced tree / skip list
O(1) splice -> doubly linked list
3. COMBINE them; use the hash map to map keys -> positions/nodes
in the other structure so updates stay O(1).
4. Verify each operation against its target.
| 模式 | 组合的结构 | 实现功能 |
|---|---|---|
| LRU 缓存 | 哈希表 + 双向链表 | O(1) get/put |
| O(1) 随机化集合 | 哈希表 + 数组 | O(1) insert/remove/random |
| 栈中的 Min in O(1) | 栈 + 辅助 min-stack | O(1) getMin |
真实系统很少需要单一的教科书结构——它们需要为特定访问模式调优的复合结构,这正是这些设计所提供的。
面试官使用这些问题来测试你是否能够从操作成本推导出组合方案,这是高性能系统设计背后的核心技能。
一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠