2021-02-13 Leetcode每日一题
题目
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input: [4,3,2,7,8,2,3,1]
Output: [5,6]
我的思路:
想麻烦了。知道可以set后查找没出现过的数字,但是以为这样做时间复杂度很高。反而自己直接想半天的方法没有通过。
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
n = len(nums)
res = []
for i in range(1,n+1):
if i not in set(nums):
res.append(i)
return res
这里需要补充一下set的排序方式,为什么这样时间复杂度反而只有O(n)
提交结果
参考思路:
一个奇淫技巧,原地修改数组。并没看太懂。
大概思路是由于每个值都是在[1,n]之间,如果每个数字都出现了一次应该是[1,2,3,4,…,n]这样的一个数组。当nums[i] = x,那么这个值应该放在下标为x-1的位置,可以标记它为负表示它在这个数组里出现过了。而对于已经为负值的数可以先取其绝对值,还原成原本的数之后再修改nums[x-1]。最终再次遍历找到仍为正的数字-1则是没有出现过的数字。
使用这种方法的原因是每个值都在[1,n]之间,因此标记的时候只要把每个值标记为不在这个区间内的数值,因此也可以选择+n。
class Solution(object):
def findDisappearedNumbers(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
for i, num in enumerate(nums):
if nums[abs(num) - 1] > 0:
nums[abs(num) - 1] *= -1
res = []
for i in range(len(nums)):
if nums[i] > 0:
res.append(i + 1)
return res