leetcode06-27每日一题:缺失的第一个正数

今天的题目如下所示:
在这里插入图片描述

这道题目的难点在于时间复杂度和空间复杂度的约束。线性时间复杂度相对来说难度没有那么大,常数空间复杂度比较棘手。于是乎我就打算先用线性空间复杂度来解题先。
最开始的方法思路是这样的:

生成一个和给定数组一样长的判定数组,这个数组的初始值全为0,然后遍历整个nums数组,把值在1到nums长度+1范围内的数字作为下标,对应到判定数组中,把判定数组中对应的值改成1。遍历完了以后再遍历一遍数组,将第一个遇到的0的下标输出,如果遍历完都没输出,就输出长度(最大值)+1的结果。

代码也不复杂,如下所示:

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        #我的方法,空间复杂度不是常数,但是更快
        if nums == []:
            return 1
        max_num = max(nums)
        if max_num < 1:
            return 1
        nums_len = len(nums)
        count_list = [0] * (nums_len+1)
        for i in nums:
            if i > 0 and i < nums_len+1:
                if count_list[i] == 0:
                    count_list[i] = 1
        for i in range(1, nums_len+1):
            if count_list[i] == 0:
                return i
        return max_num+1

写完这个后我就开始想,怎么样可以只用常数空间复杂度。想了很久没有想到,就去评论区看了看,然后根据点赞第一的评论自己写了一段,但是居然会超时:

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        #尝试失败
        i = 0
        nums_len = len(nums)
        while i < nums_len:
            while nums[i] > 0 and nums[i] <= nums_len and nums[i] != nums[nums[i]-1] and nums[i] != i + 1:
                nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]
            i += 1
        for i in range(nums_len):
            if nums[i] != i + 1:
                return i + 1
        return nums_len + 1

然后我就看了一下官方解答,官方解答有两种方法,第一种用位置作为哈希值来解答,看得我不禁拍手叫好。但是第二种方法就很让我郁闷了,明明和我后来写的思路一样,但是为什么官方解答能够运行成功,我的就不可以呢?官方解答的代码如下所示:

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        #官方2:交换位置
        n = len(nums)
        for i in range(n):
            while 1 <= nums[i] <= n and nums[nums[i] - 1] != nums[i]:
                nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
        for i in range(n):
            if nums[i] != i + 1:
                return i + 1
        return n + 1

我觉得逻辑上是跟我的那段一摸一样的,但是我的就是不能运行,实在是看不懂……如果有大佬看出来了什么端倪也麻烦指教一下,谢谢😀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值