- (有序数组)【0 ~ n-1】中缺失的 1 个数字(Easy)
- 剑指Offer 56 - I. 数组中数字出现的次数(Medium)/ 两次 / 三次 / 645. 错误的集合(Easy)/ 268. (无序数组)【0 ~ n】中缺失的 1 个数字
- 287. (含环链表解法)【1 ~ n】 重复的 1 个数(Medium)
- 剑指Offer 03. 【原地置换】数组中重复的任意 1 个数字(Easy)
- 【1 ~ n】缺两个数

题目链接

class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
n = len(nums)
for num in nums:
x = (num - 1) % n
nums[x] += n
return [i + 1 for i, num in enumerate(nums) if num <= n]
### 0206 找规律(404 ms,22.8 MB)
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
res = []
# 第一次遍历:根据数组的值找到对应的下标
for num in nums:
# 注意:因为值有可能已经取反,所以需要使用绝对值来确定下标!
idx = abs(num) - 1
# 原地改变数组:题目限定不使用额外空间
# 把值为正的数取相反数
if nums[idx] > 0:
nums[idx] *= -1
# 第二次遍历:在修改后的数组中,找出值为正的数,其下标加一则是缺少的值
# 未出现的值,其对应的下标所指向的元素都是正数
for idx in range(len(nums)):
if nums[idx] > 0:
res.append(idx + 1)
return res
442. 【1~N中】出现 2 次的数(和上面一题类似,但是对输出结果取补集)

class Solution:
def findDuplicates(self, nums: List[int]) -> List[int]:
res = []
for i in range(len(nums)):
loc = abs(nums[i]) - 1 # 以每个值的绝对值作为下标
# 若以下标指向的值已经为,则表示第二次出现,即重复
if nums[loc] < 0:
res.append(loc + 1) # 加入此重复出现的值
nums[loc] = -nums[loc] # 下标值取反进行标记
return res
41. (无序数组中)缺失的第一个正数

class Solution:
# 哈希表
def firstMissingPositive(self, nums: List[int]) -> int:
n = len(nums)
# 把不属于[1,n]的值全部修改为n+1
for i in range(n):
if nums[i] <= 0:
nums[i] = n + 1
# 把属于[1,n]的值全部取相反数
for i in range(n):
num = abs(nums[i])
if num <= n:
nums[num - 1] = -abs(nums[num - 1])
# 修改完成后,数组中第一个大于0的值,所在位置即为第一个缺失的正数
for i in range(n):
if nums[i] > 0:
return i + 1
return n + 1

class Solution:
# 置换
def firstMissingPositive(self, nums: List[int]) -> int:
n = len(nums)
for i in range(n):
# 若当前遍历的数x在[1,n]之间,那么它的正确位置(下标)应该是x-1
# 则直接交换nums[i]与nums[x-1],把x换到正确的位置上
# 交换完后新得到的nums[i]还可能在[1,n]之间,则继续把它换到正确位置上
# 直到x不在[1,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):
# 恢复后,第i个数的值应该是i+1
if nums[i] != i + 1:
return i + 1
return n + 1

1060. (有序数组中)缺失的第 K 个数

class Solution:
def missingElement(self, nums: List[int], k: int) -> int:
n = len(nums)
min_num = nums[0] # 这是有序数组的最小值
if n == 1:
return min_num + k
left, right = 0, n
while left < right:
mid = (left + right) // 2
# 关键判断:到下标 mid 为止,缺失的数字个数是否小于 k
#(因为需要保证是连续的数字)
if nums[mid] < min_num + mid + k:
left = mid + 1 # 缺失不足 k 个,第 k 个缺失在右侧
else:
right = mid # 缺失已达到或超过 k 个,向左收缩
return min_num + left + k - 1 # 返回缺失的第 k 个数
本文探讨了在不同情境下如何高效找出有序和无序数组中缺失的数字,包括通过替换、哈希表、置换等技巧,以及针对特定问题如缺失第K个数和重复数的求解方法。




 442. 【1~N中】出现 2 次的数(M) 41. 缺失的第一个正数(H) 1060.(有序数组中)缺失的第 K 个数(H)&spm=1001.2101.3001.5002&articleId=113731943&d=1&t=3&u=2d175b80347946e68fb84899fd6cfd49)
1906

被折叠的 条评论
为什么被折叠?



