文物朝代判断

标签: 数组 排序

难度: Easy

展览馆展出来自 13 个朝代的文物,每排展柜展出 5 个文物。某排文物的摆放情况记录于数组 places,其中 places[i] 表示处于第 i 位文物的所属朝代编号。其中,编号为 0 的朝代表示未知朝代。请判断并返回这排文物的所属朝代编号是否连续(如遇未知朝代可算作连续情况)。

示例 1:

输入: places = [0, 6, 9, 0, 7]
输出: True

示例 2:

输入: places = [7, 8, 9, 10, 11]
输出: True

提示:

  • places.length = 5
  • 0 <= places[i] <= 13

Submission

运行时间: 44 ms

内存: 14.7 MB

class Solution:
    def isStraight(self, nums: List[int]) -> bool:
        s = set()
        max_ = -1
        min_ = 14
        for n in nums:
            if n == 0:
                continue
            if n in s:
                return False
            else:
                s.add(n)
            max_ = max(max_, n)
            min_ = min(min_, n)
        return max_ - min_ < 5

Explain

该题解的核心思想是利用集合来检查是否有重复的朝代编号,并同时记录遇到的最大和最小的朝代编号(不考虑编号为0的未知朝代)。首先,遍历数组中的所有元素,如果元素为0,则跳过;如果元素已存在于集合中,则表示出现了重复的朝代编号,直接返回False。如果元素不在集合中,则将其添加到集合,并更新最大和最小朝代编号的记录。最后,检查最大和最小朝代编号的差是否小于5,如果是,则说明朝代编号连续或存在未知朝代,返回True;否则,返回False。

时间复杂度: O(1)

空间复杂度: O(1)

class Solution:
    def isStraight(self, nums: List[int]) -> bool:
        s = set()  # 用于存储遇到的非0朝代编号
        max_ = -1  # 记录遇到的最大朝代编号
        min_ = 14  # 记录遇到的最小朝代编号
        for n in nums:
            if n == 0:  # 跳过未知朝代
                continue
            if n in s:  # 如果朝代编号已存在,表示有重复,不连续
                return False
            s.add(n)  # 添加朝代编号到集合
            max_ = max(max_, n)  # 更新最大朝代编号
            min_ = min(min_, n)  # 更新最小朝代编号
        return max_ - min_ < 5  # 检查最大和最小朝代编号的差是否小于5

Explore

在这个题解中,如果数组中的元素已存在于集合中则返回False,是基于要求朝代编号连续且不重复的考虑。若朝代编号重复出现,意味着这些编号不能形成一个连续的区间,因为连续区间中的每个数字都是唯一的。因此,重复的朝代编号意味着这些编号不可能全部连续,违反题目的要求。

题解的这种方法能够处理大部分情况,但非所有。最大和最小朝代编号的差小于5确实可以帮助判断朝代编号是否连续,但如果数组包含未知朝代0,特别是当0位于数组两端时,0的存在不会影响最大最小朝代编号的计算,因为0被跳过。然而,如果0的数量和位置使得其它朝代编号不能形成连续区间时,仅仅判断最大最小朝代编号的差可能会导致误判。例如,数组[0, 3, 4, 2, 0]和[0, 9, 11, 12, 0]虽然最大和最小的差值均小于5,但后者并不是连续的。

题解中确实未提及所有元素均为0的情况。理论上,如果所有元素都是0,即所有朝代编号都未知,那么我们没有足够的信息来判断朝代编号是否连续。在这种情况下,可以根据题目的具体要求来返回。如果题目允许全为未知朝代时认为是连续的,可以返回True;如果需要至少一个已知的朝代编号来进行连续性判断,则应返回False。

在这个题解中使用集合而不是列表或字典的主要原因是集合在查找和插入操作中提供了更高效的性能。集合(在很多编程语言中)通常是基于哈希表实现的,使得平均时间复杂度为O(1)的成员检查和插入操作成为可能,这对于检查元素是否重复非常重要。相比之下,如果使用列表,检查元素是否存在的操作的时间复杂度为O(n),在大数据集上效率较低。字典也提供了类似的性能优势,但在这种情况下使用字典会增加不必要的复杂性,因为我们只需要记录元素的存在性,而无需存储额外的键值对信息。