|
| 1 | +# 이 문제는 배열에서 가장 자주 등장하는 k개의 요소를 찾는 문제임 |
| 2 | +# 각 숫자의 1) 등장 횟수를 계산 -> 2) 등장 횟수에 따라 정렬 -> 3) 가장 빈번한 k개의 요소를 반환의 순서로 풀이 해야 함 |
| 3 | + |
| 4 | + |
| 5 | +class Solution: |
| 6 | + def topKFrequent(self, nums: List[int], k: int): |
| 7 | + #Use Counter if you are using Python3 and you want the number of occurrences for each element: |
| 8 | + count = Counter(nums) |
| 9 | + #most_common 메서드는 Counter 객체에서 요소들의 빈도를 분석하고 정렬할 때 매우 유용 |
| 10 | + #만일 매개변수 k가 없으면 모든 요소를 빈도수 순서대로 반환 |
| 11 | + #기본적으로 빈도수가 높은 것부터 낮은 것 순서(내림차순) |
| 12 | + most_common_pairs = count.most_common(k) |
| 13 | + |
| 14 | + result = [] |
| 15 | + for element, frequency in most_common_pairs: |
| 16 | + result.append(element) |
| 17 | + |
| 18 | + return result |
| 19 | + |
| 20 | + #시간 복잡도 분석 |
| 21 | + #Counter(nums): O(n), 여기서 n은 배열의 길이 |
| 22 | + #count.most_common(k): 내부적으로 모든 요소를 정렬하므로 O(m log m)이 소요됨. 여기서 m은 고유한 요소의 수(최악의 경우 m = n). |
| 23 | + #결과 리스트 구성: O(k) |
| 24 | + #전체 시간 복잡도: O(n + m log m) ≈ O(n log n) (최악의 경우) |
| 25 | + |
| 26 | + #공간 복잡도 분석 |
| 27 | + #Counter 객체: O(m), 여기서 m은 고유한 요소의 수. |
| 28 | + #most_common 결과: O(k) |
| 29 | + #최종 결과 리스트: O(k) |
| 30 | + #전체 공간 복잡도: O(m + k) ≈ O(n) (최악의 경우) |
| 31 | + |
| 32 | + #다른 방식과의 비교 |
| 33 | + #sorted와 딕셔너리 사용 방식: |
| 34 | + #시간 복잡도: O(n log n) - Counter 방식과 동일 |
| 35 | + #공간 복잡도: O(n) - Counter 방식과 동일 |
| 36 | + #힙(heap) 사용 방식: |
| 37 | + #시간 복잡도: O(n + m log k) ≈ O(n log k) - k가 작을 때 더 효율적 |
| 38 | + #공간 복잡도: O(m + k) ≈ O(n) |
| 39 | + #버킷 정렬 방식: |
| 40 | + #시간 복잡도: O(n) - 가장 효율적 |
| 41 | + #공간 복잡도: O(n) |
| 42 | + |
| 43 | + #결론 |
| 44 | + #most_common 방식은 간결하고 가독성이 좋지만, 시간 복잡도 면에서는 버킷 정렬 방식보다 덜 효율적. |
| 45 | + #대부분의 실제 사례에서는 성능 차이가 미미하고, Python의 내장 함수들이 최적화되어 있어 most_common 방식도 충분히 빠름. |
| 46 | + #극도로 큰 데이터셋이나 성능이 매우 중요한 경우에는 버킷 정렬 방식을 고려할 수 있음. |
| 47 | + #most_common은 코드가 간결하고 직관적이라는 장점이 있음. |
| 48 | + #결론적으로, 작은 규모의 문제나 코드 가독성이 중요한 경우에는 most_common 방식이 좋은 선택이지만, 최고의 성능이 필요한 경우에는 버킷 정렬 방식이 더 효율적. |
| 49 | + |
| 50 | + |
0 commit comments