[LeetCode] 347. Top K Frequent Elements_Medium tag: Array, Heap, quickSort
2021-06-28 09:51 Johnson_强生仔仔 阅读(48) 评论(0) 编辑 收藏 举报Given an integer array nums
and an integer k
, return the k
most frequent elements. You may return the answer in any order.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2]
Example 2:
Input: nums = [1], k = 1 Output: [1]
Constraints:
1 <= nums.length <= 105
k
is in the range[1, the number of unique elements in the array]
.- It is guaranteed that the answer is unique.
Follow up: Your algorithm's time complexity must be better than O(n log n)
, where n is the array's size.
Ideas:
1. 利用collections.Counter(), 得到num: countNum 的dictionary, 再将它根据countNum来排序,取前面k个即可。
n = len(nums), m = len(distinct number )
T: O(m * lgm) S: O(m)
class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: d = collections.Counter(nums) ans, freqs = [], sorted([(d[num], num) for num in d], reverse = True) for i in range(k): ans.append(freqs[i][1]) return ans
1.2 利用dictionary的built-in function, most_common(k)
class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: return [k for k, v in Counter(nums).most_common(k)]
1.3 more fency..
class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: return zip(*Counter(nums).most_common(k))[0]
2. 利用heap和python的heapq.nlargest()method
T: O(n * lgk) S: O(k)
class Solution(object): def topKFrequent(self, nums, k): """ Given a non-empty array of integers, return the k most frequent elements. heapq.nlargest(n, iterable[, key]) Return a list with the n largest elements from the dataset defined by iterable. """ count = collections.Counter(nums) return heapq.nlargest(k, count, key=lambda x: count[x])
3. Use quickSort, 其实跟[LeetCode] 973. K Closest Points to Origin_Medium tag: Sort, heap, quickSort做法一样。
T: average O(n), worst case O(n ^ 2)
class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: count = collections.Counter(nums) uniques = list(set(nums)) n = len(uniques) l, r = 0, n - 1 while l < r: index = self.partition( uniques, count, l, r) if index == n - k: break elif index < n - k: l = index + 1 else: r = index - 1 return uniques[n - k:] def partition(self, uniques, count, l, r): pivot = uniques[r] index = l for i in range(l, r): if self.compare(count, uniques[i], pivot) < 0: uniques[index], uniques[i] = uniques[i], uniques[index] index += 1 uniques[index], uniques[r] = uniques[r], uniques[index] return index def compare(self, d, index1, index2): return d[index1] - d[index2]
4. Update in 10/24/2023 It is like counting sort, 得到最大的freq的数,然后将freq里面的list加入到ans里面,最后返回ans[:k]
T: O(n) S: O(n)
class Solution: def topKFrequent(self, nums: List[int], k: int) -> List[int]: d = collections.Counter(nums) countList = collections.defaultdict(list) largestCount = 0 for num in d: countList[d[num]].append(num) largestCount = max(largestCount, d[num]) ans = [] for i in range(largestCount, 0, -1): ans.extend(countList[i]) if len(ans) >= k: break return ans[:k]