繁体   English   中英

为什么在 O(n) 时间复杂度代码上出现 Time Limit Exceeded 错误?

[英]Why am I getting Time Limit Exceeded error on O(n) time complexity code?

问题https://leetcode.com/problems/first-missing-positive/询问:

给定一个未排序的 integer 数组 nums,返回最小的缺失正数 integer。

您必须实现一个在 O(n) 时间内运行并使用恒定额外空间的算法。

示例 1:

Input: nums = [1,2,0]
Output: 3
Example 2:

Input: nums = [3,4,-1,1]
Output: 2
Example 3:

Input: nums = [7,8,9,11,12]
Output: 1
 

Constraints:

1 <= nums.length <= 5 * 10**5
-2**31 <= nums[i] <= 2**31 - 1

因此我的代码满足了这一点:

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        nums=sorted(list(filter(lambda x: x>=0, nums)))
        nums= list(dict.fromkeys(nums))
        if 1 not in nums: return 1
        x=nums[0]
        for num in nums:
            if nums.index(num) != 0:
                dif = num - x
                if dif!=1:
                    return x + 1
                x=num
        return num+1
                
        

很高兴有人提供帮助。

如评论所述, sorted()不需要线性时间。 sorted()还会创建一个新列表,因此您的解决方案也违反了O(1) memory 约束。

这是一个线性时间,恒定空间的解决方案。 这个问题需要两件事(为简单起见,让n = len(nums) ):

  1. 一种数据结构,可以在O(1)时间内确定区间[1, n]中的正 integer 是否在nums中。 (我们有n数字要检查,并且我们的算法的运行时间必须是线性的。)对于这个问题,我们的策略是创建一个表,使得对于每个 integer i在 1 和n之间,如果i在 nums 中,则在nums[i - 1] = i (答案必须是肯定的,并且答案不能大于n + 1 - 答案为n + 1 1 的唯一方法是nums包含区间[1, n]中的每个 integer )。
  2. 就地生成数据结构以满足 memory 约束的过程。

这是一个解决方案。

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        # Match elements to their indicies.
        for index, num in enumerate(nums):
            num_to_place = num
            while num_to_place > 0 and num_to_place <= len(nums) and num_to_place != nums[num_to_place - 1]:
                next_num_to_place = nums[num_to_place - 1]
                nums[num_to_place - 1] = num_to_place
                num_to_place = next_num_to_place
        
        # Find smallest number that doesn't exist in the array.
        for i in range(len(nums)):
            if nums[i] != i + 1:
                return i + 1
        
        return len(nums) + 1

两个for循环都需要线性时间。 第二个的原因很明显,但第一个的时间分析有点微妙:

请注意, while循环包含以下条件: num_to_place != nums[num_to_place - 1] 对于此while循环的每次迭代,满足此条件的值的数量减少 1。因此,此while循环在所有迭代中最多只能执行n次,这意味着第一个for循环需要O(n)时间。

我认为,由于循环内的index ,这似乎不是O(n) ,因此直接检查而不检索索引将具有像这样的O(n)复杂性......

lst = [1,2,0]

flag = 0

if 1 not in lst:
    print(1)
else:
    arr = [_ for _ in lst if _>=0]
    amin, amax = min(arr), max(arr)

    for i in range(amin+1, amax):
        if i not in arr:
            flag = 1
            val = i
            break

    print(val) if flag else print(amax+1)

Output:-

3

每个测试用例花费的时间是:-

[1,2,0]       : 3.4332275390625e-05 seconds
[3,4,-1,1]    : 3.886222839355469e-05 seconds
[7,8,9,11,12] : 0.000102996826171875 seconds

Python 集实现为 hash 表。 所以你可以期望在 O(1) 平均中查找/插入/删除

class Solution(object):
    def firstMissingPositive(self, nums):
        nums_set = set(nums)
        result = 1
        while True:
            if result not in nums_set:
                return result
            result += 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM