基础数据结构篇(下)LeetCode 哈希表题目

80 阅读2分钟

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

image.png

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

image.png

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

image.png

参考资料

LeetCode 算法笔记 (datawhalechina.github.io)