找出数组中的幸运数

标签: 数组 哈希表 计数

难度: Easy

在整数数组中,如果一个整数的出现频次和它的数值大小相等,我们就称这个整数为「幸运数」。

给你一个整数数组 arr,请你从中找出并返回一个幸运数。

  • 如果数组中存在多个幸运数,只需返回 最大 的那个。
  • 如果数组中不含幸运数,则返回 -1

示例 1:

输入:arr = [2,2,3,4]
输出:2
解释:数组中唯一的幸运数是 2 ,因为数值 2 的出现频次也是 2 。

示例 2:

输入:arr = [1,2,2,3,3,3]
输出:3
解释:1、2 以及 3 都是幸运数,只需要返回其中最大的 3 。

示例 3:

输入:arr = [2,2,2,3,3]
输出:-1
解释:数组中不存在幸运数。

示例 4:

输入:arr = [5]
输出:-1

示例 5:

输入:arr = [7,7,7,7,7,7,7]
输出:7

提示:

  • 1 <= arr.length <= 500
  • 1 <= arr[i] <= 500

Submission

运行时间: 23 ms

内存: 16.0 MB

class Solution:
    def findLucky(self, arr: List[int]) -> int:
        # 哈希表,统计数值的频数,数值等于频数就是幸运数

        counter = Counter(arr)
        f = lambda s, t: max(list(map(lambda a: a[0] if a[0] == a[1] else -1, zip(s, t))))
        return f(counter.keys(), counter.values())

Explain

该题解首先使用Counter来统计数组arr中各元素的出现频次,得到一个哈希表。然后,通过一个lambda表达式,检查哈希表中的每个元素(数值)和其对应的频次是否相等。如果相等,则保留该数值,否则返回-1。最后通过max函数从可能的幸运数中选择最大的一个。如果没有找到任何幸运数,max函数将返回-1。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def findLucky(self, arr: List[int]) -> int:
        # 使用Counter统计arr中每个元素的出现次数
        counter = Counter(arr)
        # 定义lambda函数,检查数值和频次是否相等,相等则返回该数值,否则返回-1
        f = lambda s, t: max(list(map(lambda a: a[0] if a[0] == a[1] else -1, zip(s, t))))
        # 传入counter的键(元素)和值(频次),返回最大的幸运数或-1
        return f(counter.keys(), counter.values())

Explore

在Python中,Counter是collections模块提供的一个专门的类,用于计数可哈希对象。它本质上是一个字典,其中对象作为键,对象的计数作为值。使用Counter而不是普通字典的优势在于Counter提供了直接的方法和语法来进行元素计数,使代码更简洁、易读,并且减少了手动处理计数逻辑的错误。虽然可以使用普通字典来达到同样的目的,但使用Counter可以使代码更专注于问题的解决而非细节实现。此外,Counter还自动处理了如果元素不存在时开始计数的情况,省去了初始化步骤。

题解中的lambda函数通过zip函数直接将Counter对象的keys()和values()相结合,确保了键和值是一一对应的。在Python中,Counter的keys()和values()方法返回的顺序是匹配的,因为它们都基于同一个内部字典结构。因此,lambda函数能有效处理键和值的匹配,即使在键和值的顺序是如何的情况下也能保证一一对应。

在Python中,如果max函数的输入是一个空的可迭代对象,它会抛出ValueError异常。然而,在这个题解中,通过在map函数内使用了条件表达式,即使没有元素满足条件(元素值与出现频次相等),map函数仍会返回-1。这确保了传递给max函数的迭代器至少包含一个-1,因此max函数在这种情况下会返回-1而不是抛出异常。

题解的逻辑针对数组中所有元素都相同的情况也能正确处理。因为如果数组中的所有元素都相同,则它们的出现频次与元素值相同,满足幸运数的定义。在这种情况下,Counter将只有一个键值对,其中键是那个重复的元素,值是其出现的频次。lambda函数将检查这个键值对,如果键(元素值)与值(频次)相等,则它将被认为是幸运数。因此,这种情况也被逻辑正确处理,并不会有遗漏。