LeetCode 347. 前【K 个】高频元素(Medium)

题解

  1. 前 K 个高频元素

思路

在这里插入图片描述

class Solution:
    def topKFrequent(self, nums, k: int):
        def buildHeap(heap):
            for i in range(len(heap) // 2, -1, -1):
                heapify(heap, i)

        def heapify(arr, i):
            length = len(arr)
            left, right, largest = 2 * i + 1, 2 * i + 2, i

            if left < length and arr[left][1] < arr[largest][1]:
                largest = left
            if right < length and arr[right][1] < arr[largest][1]:
                largest = right
                
            if largest != i:
                arr[i], arr[largest] = arr[largest], arr[i]
                heapify(arr, largest)

        # if k == 0: return []
        
        stat = collections.Counter(nums)
        new_arr = list(stat.items())

        ######################################################
        # TopK:小小小顶堆(最高频)
        heap = new_arr[:k]
        buildHeap(heap) # 构建小顶堆

        for i in range(k, len(new_arr)):
            # 若当前元素 > 堆顶元素,则调整堆
            if new_arr[i][1] > heap[0][1]:
                heap[0] = new_arr[i]
                heapify(heap, 0) # 这里只需调整堆顶

        return [p[0] for p in heap] # 返回可以无序
    
        ######################################################
        # MinK:大大大顶堆(最低频)
        heap = [(p[0], -p[1]) for p in new_arr[:k]] # 存取细节与TopK不同!!!
        buildHeap(heap) # 构建大顶堆

        for i in range(k, len(new_arr)):
            # 若当前元素取反 > 堆顶元素,则调整堆
            if -new_arr[i][1] > heap[0][1]:
                heap[0] = (new_arr[i][0], -new_arr[i][1]) # 取反入堆!
                heapify(heap, 0) # 这里只需调整堆顶
        print(heap)
        return [p[0] for p in heap] # MinK

快排

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        def quick(num_cnt, k, low, high):
            idx = random.randint(low, high)
            num_cnt[low], num_cnt[idx] = num_cnt[idx], num_cnt[low]

            pivot = num_cnt[low][1] # 这里需要带上频率
            i = low
            for j in range(low + 1, high + 1):
                if num_cnt[j][1] > pivot:
                    num_cnt[i + 1], num_cnt[j] = num_cnt[j], num_cnt[i + 1]
                    i += 1
            num_cnt[low], num_cnt[i] = num_cnt[i], num_cnt[low]

            if i == k - 1:
                return num_cnt[:k]
            elif i > k - 1:
                return quick(num_cnt, k, low, i - 1)
            else:
                return quick(num_cnt, k, i + 1, high)

        count = collections.Counter(nums)
        num_cnt = list(count.items())
        topk = quick(num_cnt, k, 0, len(num_cnt) - 1)

        return [item[0] for item in topk]

在这里插入图片描述

最高频字符串

# 直接sort。。。
class Solution:
    def topKstrings(self , strings , k ):
        strings = sorted(strings)
        h = {}
        for i in strings:
            if i in h:
                h[i] += 1
            else:
                h[i] = 1
        res = sorted(h.items(), key=lambda x: x[1], reverse=True)
        return [[str(res[j][0]), str(res[j][1])] for j in range(k)]

# 快排(有bug。。)
class Solution:
    def topKstrings(self , strings , k ):
        # write code here
        import collections, random
        def random_quick(nums, l, r, k):
            random_idx = random.randint(l, r)
            nums[r], nums[random_idx] = nums[random_idx], nums[r]

            pivot = nums[r] # 固定中枢值pivot为右边界值
            i = l - 1 # i从左边界开始
            for j in range(l, r):
                if nums[j][1] < pivot[1] or (nums[j][1] == pivot[1] and nums[j][0] > pivot[0]):
                    i += 1
                    nums[i], nums[j] = nums[j], nums[i]
            nums[i + 1], nums[r] = nums[r], nums[i + 1] # 交换中枢值pivot到正确位置

            pos = i + 1       # 本次排好的中枢值元素下标
            val = pos - l + 1 # 计算当前值是第多少小的数,val表示第pos - l + 1小的数
            if k < val: random_quick(nums, l, pos - 1, k)         # 第k小的数在pivot左侧
            elif k > val: random_quick(nums, pos + 1, r, k - val) # 第k小的数在pivot右侧

        if k == 0: return []
        
        stat = collections.Counter(strings)
        new_arr = list(stat.items())

        random_quick(new_arr, 0, len(new_arr)-1, k)

        return sorted(new_arr[-k:], key=lambda x: (-int(x[1]), x[0])) # TopK
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值