Programming/leetcode

347. Top K Frequent Elements

홍열 2021. 2. 22. 21:02
728x90

주어진 리스트에서 빈도수를 세어놓고, k순위만큼 출력하는 문제

collection.Counters를 사용하면 쉽게 풀린다. 

    def topKFrequent(self, nums: [], k: int) -> []:
        lst = collections.Counter(nums).most_common(k)
        return [l[0] for l in lst]

 

책에서는 heap을 사용해서 했던데, 방법이 신기했다.

    def topKFrequent(self, nums: [], k: int) -> []:
        freqs = collections.Counter(nums)
        freqs_heap = []

        for f in freqs:
            heapq.heappush(freqs_heap, (-freqs[f], f))
        print(freqs_heap)

        topK = []
        for _ in range(k):
            topK.append(heapq.heappop(freqs_heap)[1])
        return topK

마지막으로 파이썬 다운 방식이라는데, 이해하기는 좀 어렵다

 

collections.Counter로 빈도수를 찾고, most_common(k)로 k 순서대로 받아온다. 

most_common을 호출하게 되면 (1,3),(2,2)가 나온다. 

 

여기서 zip함수를 사용하게 되면 generator이 나오고 이걸 list로 감싸주면 list가 된다

zip함수 예제는 다음가 같다 

a = [1,2,3,4,5], b = [2,3,4,5], c = [3,4,5]

list(zip(a,b))

 => [(1,2), (2,3), (3,4), (4,5)] # 같은 index끼리 튜플을 만든다.

list(zip(a,b,c))

 => [(1,2,3), (2,3,4), (3,4,5)] # 같은 index끼리 튜플을 만든다.

 

*는 list나 튜플을 언패킹하는데 사용한다. 

 

언팩

print(list(zip(*collections.Counter(nums).most_common(k))))

-> [(1, 2), (3, 2)]

언팩을 하지 않았을떄 

print(list(zip(collections.Counter(nums).most_common(k))))

->[((1, 3),), ((2, 2),)]

전혀 다른값이 된다. 

 

언팩에 대해서 좀 더 찾아보니 list나 튜플에서 자주 사용을 한다. 

abc = ['a', 'b', 'c', 'd']

abc를 출력하기 위해서는 for문으로 순회하는 방법이 있다

이때 언팩을 사용하면 한줄이면 된다. 

print(*abc)

 

print문에서도 언팩이 쓰인다.

print('a', 'b', 'c')로 넘겼을떄, print문에 몇개가 올지 모르는 상황에서 *을 사용하는 것이다. 

values에 *가 붙어 있다.

    def topKFrequent(self, nums: [], k: int) -> []:
        return list(zip(*collections.Counter(nums).most_common(k)))[0]