大于等于顺序前缀和的最小缺失整数

标签: 数组 哈希表 排序

难度: Easy

给你一个下标从 0 开始的整数数组 nums 。

如果一个前缀 nums[0..i] 满足对于 1 <= j <= i 的所有元素都有 nums[j] = nums[j - 1] + 1 ,那么我们称这个前缀是一个 顺序前缀 。特殊情况是,只包含 nums[0] 的前缀也是一个 顺序前缀

请你返回 nums 中没有出现过的 最小 整数 x ,满足 x 大于等于 最长 顺序前缀的和。

示例 1:

输入:nums = [1,2,3,2,5]
输出:6
解释:nums 的最长顺序前缀是 [1,2,3] ,和为 6 ,6 不在数组中,所以 6 是大于等于最长顺序前缀和的最小整数。

示例 2:

输入:nums = [3,4,5,1,12,14,13]
输出:15
解释:nums 的最长顺序前缀是 [3,4,5] ,和为 12 ,12、13 和 14 都在数组中,但 15 不在,所以 15 是大于等于最长顺序前缀和的最小整数。

提示:

  • 1 <= nums.length <= 50
  • 1 <= nums[i] <= 50

Submission

运行时间: 20 ms

内存: 15.9 MB

class Solution:
    def missingInteger(self, nums: List[int]) -> int:
        s=nums[0]
        i=1
        n=len(nums)
        while i<n:
            if nums[i]==nums[i-1]+1:
                s+=nums[i]
            else:
                break
            i+=1
        while True:
            if s in nums:
                s+=1
            else:
                return s
            



        

Explain

题解首先通过遍历数组nums来寻找最长的顺序前缀,并计算这个顺序前缀的和s。顺序前缀是指数组的一个片段,其中每个元素都比前一个元素大1。一旦找到了顺序前缀,算法就会停止累加s。接下来,算法使用一个无限循环来寻找大于等于s的最小的不在数组nums中的整数。循环中,如果s在数组中,s就递增1,否则返回s作为结果,因为这是第一个不在数组中且大于等于顺序前缀和的整数。

时间复杂度: O(n)

空间复杂度: O(1)

class Solution:
    def missingInteger(self, nums: List[int]) -> int:
        s = nums[0]  # 初始化s为nums的第一个元素,即最小的顺序前缀和
        i = 1         # 从第二个元素开始遍历
        n = len(nums) # 获取数组长度
        # 寻找最长的顺序前缀
        while i < n:
            if nums[i] == nums[i-1] + 1: # 检查当前元素是否比前一个元素大1
                s += nums[i]           # 如果是,则加到s上
            else:
                break                   # 如果不是,结束循环
            i += 1
        # 寻找最小的不在数组中的大于等于s的整数
        while True:
            if s in nums:   # 如果s在数组中
                s += 1      # s递增1
            else:
                return s    # 否则返回s

Explore

如果已知数组中所有元素都严格顺序递增,每个元素确实都是前一个元素加1,那么算法中检查每个元素是否满足顺序条件的步骤可以简化。例如,可以直接使用数组的长度和首元素计算整个数组的和,即 s = n * (首元素 + 末元素) / 2,这里的 n 是数组的长度。这种方法利用等差数列求和公式,避免了逐一检查每个元素,从而优化了计算过程。

使用 `while True` 循环确实可能存在效率问题,特别是在数组很大或者大于等于 s 的最小缺失整数远大于数组中的最大值时。每次循环都需要检查 s 是否在数组中,这个操作的时间复杂度是 O(n),其中 n 是数组长度。因此,总的时间复杂度可能高达 O(n*m),其中 m 是从 s 开始直到找到不在数组中的第一个整数的次数。为了优化这一过程,可以先将数组元素存储在哈希表中,这样检查一个元素是否在数组中的时间复杂度降为 O(1),从而显著提高整体效率。

是的,使用哈希表来存储数组元素会更高效。哈希表支持平均时间复杂度为 O(1) 的查找操作,这可以显著提高检查一个整数是否存在于数组中的效率。与直接在数组中查找每个元素相比(平均时间复杂度为 O(n)),哈希表可以减少查找时间,特别是在多次查找操作时尤为明显。此外,构建哈希表的时间复杂度为 O(n),因此整体时间复杂度为 O(n),这在多次查询的情况下是优于直接搜索的。

是的,条件 `nums[i] != nums[i-1] + 1` 包括了任何导致顺序被打断的情况,无论是数字的重复还是更大的跳跃。此条件确保只有当当前元素正好是前一个元素加1时顺序才继续。任何其他情况,如元素相同(重复)或当前元素大于前一个元素加1的情况(大跳跃),都会导致循环终止,因为这些情况都不满足严格递增的顺序要求。