※ 41. 缺失的第一个正数
这题的hash法我看懂了,就是没时间写注释
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
n = len(nums)
for i in range(n):
if nums[i] <= 0:
nums[i] = n + 1
for i in range(n):
num = abs(nums[i])
if num <= n:
nums[num - 1] = -abs(nums[num - 1])
for i in range(n):
if nums[i] > 0:
return i + 1
return n + 1
复用上题的hash法
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
n=len(nums)
for i in range(n):
num=abs(nums[i])
if num<=n:
nums[num-1]=-abs(nums[num-1])
ans=[]
for i in range(n):
if nums[i]>0:
ans.append(i+1)
return ans
- 数学tricky
用求和公式求出 [ 0 ⋯ n ] [0\cdots n] [0⋯n] 的和,减去数组中所有数的和,就得到了缺失数字
求和,题解用的高斯求和,有玩家认为会溢出,提出了以下方法:
public int missingNumber(int[] nums) {
int sum = 0;
for (int i = 1; i <= nums.length; i++) {
sum += i;
sum -= nums[i - 1];
}
return sum;
}
- 位运算
先和
[
0
⋯
n
]
[0\cdots n]
[0⋯n]的数都xor一遍,根据a ^ a = 0
的定理,a ^ a ^ b = b
,就找到了
class Solution:
def missingNumber(self, nums):
missing = len(nums)
for i, num in enumerate(nums):
missing ^= i ^ num
return missing
复用剑指的代码
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
n = len(nums)
for i in range(n):
nums[i] -= 1
for i in range(n):
while nums[i] != i:
if nums[i] == nums[nums[i]]:
return nums[i] + 1
t = nums[i]
nums[i] = nums[t]
nums[t] = t
剑指 Offer 03. 数组中重复的数字
和前面的一道题可以合起来看看
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
n = len(nums)
for i in range(n):
# 有一个顾虑,就是如果不存在数字i会出现死循环,
# 但不用担心,如 [1, 1, 1] ,会直接返回掉
while nums[i] != i:
if nums[i] == nums[nums[i]]:
return nums[i]
# ↓ 这么干就凉了
# nums[i], nums[nums[i]] = nums[nums[i]], nums[i]
tmp = nums[nums[i]]
nums[nums[i]] = nums[i]
nums[i] = tmp
return -1