https://leetcode.com/problems/top-k-frequent-elements/
Given an integer array
numsand an integerk, return thekmost frequent elements. You may return the answer in any order.
class Solution:
# Counter 사용, 소팅을 사용하므로 시간복잡도는 O(nlogn) 고정
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
num_freq = collections.Counter(nums)
return [i[0] for i in sorted(num_freq.items(), key=lambda x: x[1], reverse=True)[:k]]
collections.Counter() 를 사용하여 nums 에 들어있는 숫자들을 카운팅한다.
딕셔너리의 밸류를 내림차순으로 정렬한 후, k 만큼 슬라이싱하여 리턴한다.
위 방법은 무조건 전체 리스트를 정렬하므로 의 시간복잡도를 가지게 된다.
Follow up: Your algorithm's time complexity must be better than
O(n log n), where n is the array's size.
class Solution:
# Counter의 most_common 메소드 이용, 시간복잡도는 k가 n보다 작을 때 O(nlogk)
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
num_freq = collections.Counter(nums).most_common(k)
return [i[0] for i in num_freq]
처음 방법의 경우, 결과값을 리턴하기 위해 딕셔너리의 전체 밸류를 소팅한 후 슬라이싱을 하였다. 이렇게 되면, k 값이 n 에 비해 많이 작더라도 고정적으로 의 시간복잡도를 가지는데, Follow up에서 보다 작은 시간복잡도를 가져야한다는 조건을 걸어서 다른 방법을 찾아보기로 하였다.
Counter() 클래스에 포함된 most_common(n) 이라는 메소드를 찾게 되었는데, 이는 카운터로 생성된 딕셔너리에서 밸류가 높은순서대로 n개의 원소만 리턴해주기 때문에 이 메소드를 이용하여 필요한 갯수만큼만 가져오기로 했다.
most_common(n) 은 어제 풀었던 우선순위 큐를 사용하는 메소드다. 파이썬에 내장된 heapq 를 사용하여 우선순위 순서대로 원하는 갯수만큼 뽑아내게 되는데, 이 방식의 시간 복잡도는 총 n개의 원소에서 k개를 뽑아낼 때 로 문제에서 요구하는 조건인 보다 작아지게 된다.
https://stackoverflow.com/questions/29240807/python-collections-counter-most-common-complexity
class Solution:
# Counter의 most_common 메소드 이용, 시간복잡도는 k가 n보다 작을 때 O(nlogk)
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
# zip과 *(언패킹)을 사용
return list(zip(*collections.Counter(nums).most_common(k)))[0]
위 코드는 책에서 제시한 방법으로, zip 과 *(unpacking) 을 이용하여 한 줄로 만든 코드다.
zip 의 경우, 여러개의 리스트에서 같은 인덱스의 원소를 가져와 하나로 합치는 함수다. 길이가 다를 경우 가장 짧은 리스트를 기준으로 반환해준다.
*(unpacking) 은 말 그대로 리스트나 세트로 묶여있는 원소들을 풀어주는 것이다.
따라서 위 코드는 most_common() 으로 받아온 [[key1, value1], [key2, value2] ... ] 형태의 리스트를 언패킹해 [key1, value1], [key2, value2] ... 형태로 만들어 준 뒤, 각 리스트의 같은 인덱스만 zip 하여 최종적으로 [key1, key2, ... ], [value1, value2, ... ] 형태의 두 리스트로 만들어주는 코드이다.