求解前K个高频元素——sorted()方法和lambda匿名函数的应用

求解前K个高频元素

题目描述:

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

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

输入: nums = [1], k = 1
输出: [1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/top-k-frequent-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

求的是前K高频的元素,那首先要统计每个元素出现的次数,并将元素以及其出现的次数以key和value的形式放入一个字典中。然后再以字典中的value(也就是其对应的key出现在原数组中的次数)为准,取出前K高value对应的key放入结果中返回。

主要的问题:

统计每个元素出现的次数只需采用一个for循环即可,用dic_count存放结果

for i in nums:   #遍历数组nums,将所有出现的数字及其出现次数保存与dic_count中
    if i not in dic_count:
        dic_count.update({i: nums.count(i)})
    else:
        continue

如何方便地取出字典中value前K高的key值,首先想到的是排序,排序之后按照从头到尾的顺序前K个key就非常方便,但是,字典的排序实现比较困难。这里学习了sorted方法和lambda匿名函数,来实现这一算法。

lt = sorted(dic_count.items(), key=lambda x: x[1], reverse=True)

现在看上去是不是一头雾水,先别急,看了下面对sorted()和lambda的解释你就会豁然开朗。

sorted()方法

sorted() 函数与 reversed() 函数类似,该函数接收一个可迭代对象作为参数,返回一个对元素排序的列表。

在交互式解释器中测试该函数,可以看到如下运行过程:

a = [20, 30, -1.2, 3.5, 90, 3.6]
sorted(a)
[-1.2, 3.5, 3.6, 20, 30, 90]
a
[20, 30, -1.2, 3.5, 90, 3.6]

从上面的运行过程来看,sorted() 函数也不会改变所传入的可迭代对象,该函数只是返回一个新的、排序好的列表。

在使用 sorted() 函数时,还可传入一个 reverse 参数,如果将该参数设置为 True,则表示反向排序。例如如下测试过程:

sorted(a, reverse = True)
[90, 30, 20, 3.6, 3.5, -1.2]

在调用 sorted() 函数时,还可传入一个 key 参数,该参数可指定一个函数来生成排序的关键值。比如希望根据字符串长度排序,则可为 key 参数传入 len 函数。例如如下运行过程:

b = ['fkit', 'crazyit', 'charlie', 'fox', 'Emily']
sorted(b, key = len)
['fox', 'fkit', 'Emily', 'crazyit', 'charlie']

通过 sorted() 函数的帮助,程序可对可迭代对象按照由小到大的顺序进行遍历。

lambda匿名函数

现在再回头看看这一行代码:

lt = sorted(dic_count.items(), key=lambda x: x[1], reverse=True)

解释一下就是将dic_count.items()以lambda x:x[1]为关键值反向排序。

lambda x:x[1]则是用到了匿名函数lambda

ambda函数又称匿名函数,匿名函数就是没有名字的函数,函数没有名字也行?
当然可以啦。有些函数如果只是临时一用,而且它的业务逻辑也很简单时,就没必要非给它取个名字不可。

要理解匿名函数,先来看下面一段代码:

add=lambda x,y:x+y

print(add(1,5))

这里的x,y是a的两个参数,冒号后面则是返回值。

也就相当于:

def add(x,y):
    return x+y

add(1,5)

所以如果我们再再回来看那一行代码

lt = sorted(dic_count.items(), key=lambda x: x[1], reverse=True)

其实也就是将dic_count.items()以dic_count.items()[1]为关键值反向排序

这样就获得了以元组为元素的列表,而这个列表是按照元祖索引为1的值(也就是出现次数)从大到小排列的,剩下的就很简单了,只需拿出你需要的K个值就可以了。

求解前K个高频元素的源代码:

def topKFrequent(nums, k):
    res = []
    count = 0
    dic_count = {}
    for i in nums:  # 遍历数组nums,将所有出现的数字及其出现次数保存与dic_count中
        if i not in dic_count:
            dic_count.update({i: nums.count(i)})
        else:
            continue
    lt = sorted(dic_count.items(), key=lambda x: x[1], reverse=True)
    print(lt)
    for i in lt:  # 将前k高频元素放入res
        if count < k:
            res.append(i[0])
            count += 1
        else:
            break
    print(res)

感想:sorted和lambda真好真好用呀

posted @ 2019-07-31 18:41  Sheppard_xxx  阅读(299)  评论(0编辑  收藏  举报