Python'da yığın kullanan En Sık Kullanılan K Kelime [duplicate]
En Çok Sık Kullanılan Kelimeler Leetcode problemini O (N log K) zamanında çözmeye çalışıyorum ve istenmeyen bir sonuç alıyorum. Python3 kodum ve konsol çıktım aşağıdadır:
from collections import Counter
import heapq
class Solution:
def topKFrequent(self, words: List[str], k: int) -> List[str]:
counts = Counter(words)
print('Word counts:', counts)
result = []
for word in counts:
print('Word being added:', word)
if len(result) < k:
heapq.heappush(result, (-counts[word], word))
print(result)
else:
heapq.heappushpop(result, (-counts[word], word))
result = [r[1] for r in result]
return result
----------- Console output -----------
Word counts: Counter({'the': 3, 'is': 3, 'sunny': 2, 'day': 1})
Word being added: the
[(-3, 'the')]
Word being added: day
[(-3, 'the'), (-1, 'day')]
Word being added: is
[(-3, 'is'), (-1, 'day'), (-3, 'the')]
Word being added: sunny
[(-3, 'is'), (-2, 'sunny'), (-3, 'the'), (-1, 'day')]
Ben test case çalıştırdığınızda ["the", "day", "is", "sunny", "the", "the", "sunny", "is", "is"]ile K = 4, ben kelime bulmak thelistenin sonuna (sonra kaydırılır alır day) bir zamanlar isikisi de ebeveyn ihtiyacı sadece <= çocuk olmak beri 3. sayısıdır Bu mantıklı olsa bile eklenir ve çocuklara hiçbir şekilde sipariş verilmedi. Yana (-2, 'sunny')ve (-3, 'the')her ikisi de> (-3, 'is'), yığın değişmez, aslında, olsa bile korunur (-3, 'the')< (-2, 'sunny')ve sağ çocuğudur (-3, 'is'). Beklenen sonuç, ["is","the","sunny","day"]kodumun çıktısı olduğu zamandır ["is","sunny","the","day"].
Bu sorunu O (N log K) zamanında çözmek için yığın kullanmalı mıyım ve eğer öyleyse, istenen sonucu elde etmek için kodumu nasıl değiştirebilirim?
Yanıtlar
Kullanım konusunda doğru yoldasınız heapqve Counterk: ile ilgili olarak bunları nasıl kullandığınıza dair küçük bir değişiklik yapmanız yeterlidir (herhangi bir şey eklemeden önce tüm sayıları yinelemeniz gerekir result):
from collections import Counter
import heapq
class Solution:
def topKFrequent(self, words: List[str], k: int) -> List[str]:
counts = collections.Counter(words)
max_heap = []
for key, val in counts.items():
heapq.heappush(max_heap, (-val, key))
result = []
while k > 0:
result.append(heapq.heappop(max_heap)[1])
k -= 1
return result
Daha önce O (N log k) olma gerekliliğini okumamıştım, bunu başarmak için yukarıdaki çözümde bir değişiklik var:
from collections import Counter, deque
import heapq
class WordWithFrequency(object):
def __init__(self, word, frequency):
self.word = word
self.frequency = frequency
def __lt__(self, other):
if self.frequency == other.frequency:
return lt(other.word, self.word)
else:
return lt(self.frequency, other.frequency)
class Solution:
def topKFrequent(self, words: List[str], k: int) -> List[str]:
counts = collections.Counter(words)
max_heap = []
for key, val in counts.items():
heapq.heappush(max_heap, WordWithFrequency(key, val))
if len(max_heap) > k:
heapq.heappop(max_heap)
result = deque([]) # can also use a list and just reverse at the end
while k > 0:
result.appendleft(heapq.heappop(max_heap).word)
k -= 1
return list(result)
Bir yığınla uğraşmanıza gerek yok. Counter () zaten en yaygın öğeleri döndürmek için bir yönteme sahiptir.
>>> c = Counter(["the", "day", "is", "sunny", "the", "the", "sunny", "is", "is"])
>>> c.most_common(4)
[('the', 3), ('is', 3), ('sunny', 2), ('day', 1)]