K个数、K个点、K个元素,3K堆排序,类比三解题!

面试题17.14.最小K个数

https://leetcode-cn.com/problems/smallest-k-lcci/solution/mian-shi-ti-1714zui-xiao-kge-shu-ji-chu-k9jd8/

难度:中等

题目:

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

提示:

  • 0 <= len(arr) <= 100000
  • 0 <= k <= min(100000, len(arr))

示例:

输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]

分析

这道题之所以定义为堆排序类型题,就是因为可以任意顺序返回。 这里推排序有两种思路:

  1. 小根堆:每次获取的数据都无脑入堆,然后最终将前K个数字返回
  2. 大根堆:仅维护K个长度的堆,由于python没有,需要入赋值,如果当前的数大于heap[0],则堆顶出堆,当前数入堆,最终返回。

至于 return sorted(arr)[:k] 的写法,面试时候不怕被打,你就这么写。

解题:

import heapq

class Solution:
    def smallestK(self, arr, k):
        if k == 0:
            return []
        hq = []
        for i in arr:
            if len(hq) < k:
                heapq.heappush(hq, -i)
            else:
                if hq[0] < -i:
                    heapq.heappop(hq)
                    heapq.heappush(hq, -i)
        return [-i for i in hq]

347.前K个高频元素

https://leetcode-cn.com/problems/top-k-frequent-elements/solution/347qian-kge-gao-pin-yuan-su-nei-zhi-han-zlfi7/

难度:中等

题目:

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

提示:

  • 1 <= nums.length <= 10 ^ 5
  • k 的取值范围是 [1, 数组中不相同的元素的个数]
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

示例:

示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2:
输入: nums = [1], k = 1
输出: [1]

分析

遇到重复数字求频率,首先要想到Counter计数原则,将当前的数组转换为hash表 num:frequency 的类型然后再做操作。
即: dic = collections.Counter(nums)

分享两种方法(虽然面试官更希望你写第二种,但如果同时写出第一种,能展示出你对基础模块的掌握度):

1.sorted方法

使用sorted自带的排序和列表切片后返回,可以压缩到一行代码

2.堆排序

这道题提及了任意顺序返回均可,那就可以通过使用堆的方法来解决了。这道题使用小根堆很方便。

类似的题目有:

面试题17.14.最小K个数

sorted解题:

from collections import Counter
class Solution:
    def topKFrequent(self, nums, k):
        return [x[0] for x in sorted(Counter(nums).items(),key = lambda x: x[1],reverse=True)[:k]]

堆排序解题:

from collections import Counter
import heapq

class Solution:
    def topKFrequent(self, nums, k):
        dic = Counter(nums)
        hp = []
        for num, req in dic.items():
            if len(hp) < k:
                heapq.heappush(hp, (req, num))
            else:
                if req > hp[0][0]:
                    heapq.heappop(hp)
                    heapq.heappush(hp, (req, num))
        return [x[1] for x in hp]

973.最接近原点的K个点

https://leetcode-cn.com/problems/k-closest-points-to-origin/solution/973zui-jie-jin-yuan-dian-de-kge-dian-pyt-4jro/

难度:中等

题目:

我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。

(这里,平面上两点之间的距离是欧几里德距离。)

你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。

提示:

  • 1 <= K <= points.length <= 10000
  • -10000 < points[i][0] < 10000
  • -10000 < points[i][1] < 10000

示例:

示例 1:

输入:points = [[1,3],[-2,2]], K = 1
输出:[[-2,2]]
解释: 
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。
示例 2:

输入:points = [[3,3],[5,-1],[-2,4]], K = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)

分析

遇到求前K的题目,内置的sorted和堆排序无脑安排上就对了,类似的题目有:

这道题同样的,我们使用堆排序(大根堆)来完成解题,维护一个K大的堆,然后每次判断距离是否比堆顶的数字大。
如果比堆顶数字大,弹出堆顶,将当前距离及点信息以列表方式入堆即可。

解题:

import heapq


class Solution:
    def kClosest(self, points, k):
        hp = []
        for point in points:
            distance = sum(map(lambda x: abs(x ** 2), point))
            if len(hp) < k:
                heapq.heappush(hp, [-distance, point])
            else:
                if -distance > hp[0][0]:
                    heapq.heappop(hp)
                    heapq.heappush(hp, [-distance, point])
        return [point for distance, point in hp]

欢迎关注我的公众号: 清风Python,带你每日学习Python算法刷题的同时,了解更多python小知识。

我的个人博客:https://qingfengpython.cn

力扣解题合集:https://github.com/BreezePython/AlgorithmMarkdown

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容