03.01 哈希表
0220 存在重复元素 III
解题思路
桶排序。将 indexDiff 个数字分到 indexDiff 个桶中,从而在 O(1) 的复杂度确定是否有与当前值 nums[i] 接近的数,即[nums[i] - valueDiff, nums[i] + valueDiff](检查目标桶内是否有元素)。
getId(x, w)是计算桶的编号的函数。
具体做法:根据当前值nums[i],计算桶的编号。
- 如果已经存在桶,则说明前面已出现接近的数。
- 如果不存在该桶,则检查相邻的两个桶
- 建立目标桶,并删除下标范围超出indexDiff范围的桶
代码
class Solution:
def containsNearbyAlmostDuplicate(self, nums: List[int], indexDiff: int, valueDiff: int) -> bool:
def getId(x, w):
return x // w if x >= 0 else (x + 1) // w - 1
d = {}
w = valueDiff + 1
for i in range(len(nums)):
m = getId(nums[i], w)
if m in d:
return True
if m - 1 in d and abs(nums[i] - d[m-1]) <= valueDiff:
return True
if m + 1 in d and abs(nums[i] - d[m+1]) <= valueDiff:
return True
d[m] = nums[i]
if i >= indexDiff:
del d[getId(nums[i - indexDiff], w)]
return False
0041 缺失的第一个正数
解题思路
根据题意,该题的答案最大值为n + 1。先遍历一遍数组,将小于等于0的数都赋值为n + 1。这样数组中元素全部为正。
将当前数组看成是一个哈希表。将对应位置元素绝对值取负。这样即可标记该正数已经出现过。
最后遍历一遍数组,元素值为正的即为缺失的正数。
代码
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
0149 直线上最多的点数
解题思路
将数组 points 的点存到 set 中,对 points 中的点进行遍历,每次弹出 1 个点,并计算其他点与该点的斜率,通过 defaultdict 记录斜率数,斜率数的最大值即为直线上最多的点。
代码
class Solution:
def maxPoints(self, points: List[List[int]]) -> int:
cnt = set((x, y) for x, y in points)
if len(cnt) <= 2:
return len(points)
ans = 0
for _ in range(1, len(cnt)):
x1, y1 = cnt.pop()
slp = defaultdict(lambda: 1)
for x2, y2 in cnt:
s = (y2 - y1) / (x2 - x1) if x1 != x2 else float('inf')
slp[s] += 1
ans = max(ans, max(slp.values()))
return ans