1 问题描述
给定一个长度为 n n n的数组,数组中数的值在 [ 1 , n ] [1,n] [1,n]之间,找出属于 [ 1 , n ] [1,n] [1,n]但不在数组中的数。
2 实现1
先创建一个数组out,其长度为 n n n,数组元素为 [ 1 , n ] [1,n] [1,n]共 n n n个数。然后遍历原始数组nums,将out[nums[i]]赋值为0,这样就将数组中存在的数赋值0了,之后,再将out中不为0的数输出即可。
本质上,这种思想是建立了一个哈希表out,来对哈希表进行处理的方法。
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
out = list(range(1, 1+len(nums)))
for num in nums:
out[num-1] = 0
final_out = []
for o in out:
if o != 0:
final_out.append(o)
return final_out
时间复杂度 O ( n ) O(n) O(n),需要额外使用长度为 n n n和最差长度为 n n n的空间,即最多要用到 2 n 2n 2n的额外空间。
3 实现2
由于数组长度为 n n n,数值区间长度也为 n n n,因此,可以考虑令哈希表为这个数组本身。
根据官方题解的提供的思路,我们可以遍历数组中的所有元素,然后令元素对应索引位置的数加上 n n n,这样,到最后,数组中小于 n n n的元素的索引就对应着没有出现在数组中的数。
注意在实际索引时要对 n n n取余,因为有可能这个数已经加了好几个 n n n。
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
out = []
n = len(nums)
for num in nums:
nums[num % n - 1] += n
for i in range(n):
if nums[i] <= n:
out.append(i+1)
return out
时间复杂度 O ( n ) O(n) O(n),不需要除了输出外的其他额外空间,空间复杂度 O ( 1 ) O(1) O(1)。