โจทย์
ออกแบบ Data Structure รองรับ operations ทั้ง 3 ใน Average O(1):
insert(val): เพิ่ม val ถ้ายังไม่มี → True, ถ้ามีแล้ว → Falseremove(val): ลบ val ถ้ามี → True, ถ้าไม่มี → FalsegetRandom(): คืนค่า random element จากชุดปัจจุบัน (ทุก element โอกาสเท่ากัน)
วิธีแก้: Array + Hash Map (Index Mapping)
- Array (list): เก็บ elements รองรับ getRandom ด้วย
random.choice()O(1) - Hash Map (dict):
val → index ใน arrayรองรับ insert/remove/lookup O(1) - Trick การลบ O(1): Swap with last element แล้ว pop()
การติดตั้ง (Python Implementation)
import random
class RandomizedSet:
def __init__(self):
self.val_to_index = {} # val -> index in array
self.elements = [] # array of values
def insert(self, val: int) -> bool:
if val in self.val_to_index:
return False
self.val_to_index[val] = len(self.elements)
self.elements.append(val)
return True
def remove(self, val: int) -> bool:
if val not in self.val_to_index:
return False
idx = self.val_to_index[val]
last_val = self.elements[-1]
# Swap with last element
self.elements[idx] = last_val
self.val_to_index[last_val] = idx
# Remove last
self.elements.pop()
del self.val_to_index[val]
return True
def getRandom(self) -> int:
return random.choice(self.elements)
# ทดสอบ
ob = RandomizedSet()
print(ob.insert(1)) # True
print(ob.remove(2)) # False
print(ob.insert(2)) # True
print(ob.getRandom()) # 1 or 2 (random)
print(ob.remove(1)) # True
print(ob.insert(2)) # False (already exists)
print(ob.getRandom()) # 2
Output
True False True 1 (or 2) True False 2
การทำงานของ Remove (Swap with Last)
Before remove(1): elements=[1,2], map={1:0, 2:1}
idx=0, last_val=2
Swap: elements[0]=2, map[2]=0
Pop: elements=[2], map={2:0}
Result: elements=[2], map={2:0} ✓
Complexity
insert: O(1) average (dict + list append)remove: O(1) average (dict lookup + swap + pop)getRandom: O(1) (random.choice on list)- Space: O(n)
ข้อควรระวัง
random.choice()ต้องการ list ที่ไม่ว่าง (handle empty case)- Swap technique ทำให้ index ของ last element เปลี่ยน → ต้อง update map ด้วย
- Python dict insertion order preserved (3.7+) แต่ไม่เกี่ยวกับ logic นี้
สรุป
Insert Delete GetRandom O(1) เป็นโจทย์คลาสสิก ใช้ Array + Hash Map (Index Mapping) พร้อมเทคนิค Swap with Last สำหรับ remove O(1) รูปแบบนี้ใช้ได้หลายที่ เช่น RandomizedSet, LRU Cache variants, etc.
หากมีข้อสงสัย สามารถถามได้ในส่วนความคิดเห็นครับ