今天的题目如下所示:
这道题目的难点在于时间复杂度和空间复杂度的约束。线性时间复杂度相对来说难度没有那么大,常数空间复杂度比较棘手。于是乎我就打算先用线性空间复杂度来解题先。
最开始的方法思路是这样的:
生成一个和给定数组一样长的判定数组,这个数组的初始值全为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
我觉得逻辑上是跟我的那段一摸一样的,但是我的就是不能运行,实在是看不懂……如果有大佬看出来了什么端倪也麻烦指教一下,谢谢😀