Middle — Senior
Kaip apdoroti duomenų srautą medianai apskaičiuoti turint ribotą atmintį?
sobes.tech AI
Atsakymas iš AI
Skaičiuojant medianą duomenų sraute, kai atmintis yra ribota, naudojami algoritmai, kurie nereikalauja saugoti visus elementus. Vienas populiariausių būdų yra palaikyti dvi duomenų struktūras (pavyzdžiui, dvi krūvas):
- Didžiausia krūva apatinės pusės elementams
- Mažiausia krūva viršutinės pusės elementams
Kai įdedamas naujas skaičius, jis pridedamas į vieną iš krūvų, tada jų dydžiai subalansuojami taip, kad jų skirtumas nebūtų didesnis nei 1. Medianą sudaro arba didžiausios krūvos šaknies elementas (jei jis didesnis), arba abiejų krūvų vidurkis.
Šis metodas leidžia gauti medianą per O(log n) laiką kiekvienam elementui ir naudoti atmintį proporcingai elementų skaičiui, tačiau neįrašant viso srauto.
Pavyzdys Python kalba:
import heapq
class MedianFinder:
def __init__(self):
self.low = [] # maksimali krūva (invertuoti reikšmes)
self.high = [] # minimali krūva
def add_num(self, num):
heapq.heappush(self.low, -num)
# Perkelti maksimalią iš low į high
if self.low and self.high and (-self.low[0]) > self.high[0]:
val = -heapq.heappop(self.low)
heapq.heappush(self.high, val)
# Balansuoti dydžius
if len(self.low) > len(self.high) + 1:
val = -heapq.heappop(self.low)
heapq.heappush(self.high, val)
elif len(self.high) > len(self.low):
val = heapq.heappop(self.high)
heapq.heappush(self.low, -val)
def find_median(self):
if len(self.low) > len(self.high):
return float(-self.low[0])
else:
return (-self.low[0] + self.high[0]) / 2
# Naudojimas:
finder = MedianFinder()
for num in [5, 15, 1, 3]:
finder.add_num(num)
print(finder.find_median())
Šis metodas yra efektyvus srautinio apdorojimo su ribota atmintimi atveju.