数据结构--哈希表与力扣HOT100题结合

目录

1. 引言

2. 哈希表基础

3. 哈希表的应用场景

4. 题目解析:两数之和

5. 题目解析:字母异位词

6. 题目解析:最长连续序列

7. 哈希表与其他数据结构的比较

8. 哈希表的实际应用案例


1. 引言

  • 简介:简要介绍数据结构的重要性及其在编程中的应用。
  • 哈希表简介

    哈希表,也称为散列表,是一种通过键值对存储数据的数据结构。它通过使用哈希函数将输入(键)转换为索引值,从而在表中的位置存储相应的输出(值)。哈希表的主要优势在于它可以提供非常快速的数据插入和查找操作,理论上可达到接近常数时间的性能。

    哈希表的工作原理基于以下步骤:

  • 使用哈希函数处理键,生成一个哈希码。
  • 将哈希码映射到表中的一个位置。
  • 在该位置存储或检索值。

2. 哈希表基础

  • 定义:哈希表是一种数据结构,它提供了快速的数据访问机制。在哈希表中,数据以键值对的形式存储,其中键是通过哈希函数转换后的结果,而值是与键相关联的数据。哈希表的关键在于哈希函数的设计,它决定了如何将键分布到哈希表的存储位置。
  • 实现
    # 创建一个哈希表(字典)
    my_hash_table = {}
    
    # 添加键值对
    my_hash_table["key1"] = "value1"
    my_hash_table["key2"] = "value2"
    
    # 访问和修改值
    print(my_hash_table["key1"])  # 输出: value1
    
    # 更新值
    my_hash_table["key1"] = "updated_value1"
    print(my_hash_table["key1"])  # 输出: updated_value1

  • 优势与局限
  • 优势

  • 快速查找:哈希表提供了平均时间复杂度为O(1)的查找效率。
  • 灵活的键:可以使用各种类型的数据作为键,只要它们可哈希。
  • 动态大小:许多哈希表实现会自动调整大小以适应存储需求。
  • 局限
  • 冲突处理:不同的键可能产生相同的哈希值,需要有效的冲突解决策略。
  • 空间效率:哈希表可能需要较多的内存空间来减少冲突并保持快速访问。
  • 哈希函数设计:设计一个良好的哈希函数是实现高效哈希表的关键,这可能具有挑战性。

3. 哈希表的应用场景

  • 快速查找:讨论哈希表在快速查找数据中的应用。
  • 计数问题:展示如何使用哈希表进行元素计数。
  • 去重:说明哈希表在数据去重中的作用。

4. 题目解析:两数之和

  • 问题描述

    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

    你可以按任意顺序返回答案。

    示例 1:

    输入:nums = [2,7,11,15], target = 9
    输出:[0,1]
    解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
    

    示例 2:

    输入:nums = [3,2,4], target = 6
    输出:[1,2]
    

    示例 3:

    输入:nums = [3,3], target = 6
    输出:[0,1]
    

    提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案
  • 解决方案
    • 算法逻辑
    • 创建一个空的哈希表,用于存储已经遍历过的数组元素及其对应的索引。
    • 遍历整数数组 nums
    • 对于数组中的每个元素,计算 target 与当前元素的差值,即 complement = target - nums[i]
    • 检查 complement 是否存在于哈希表中:
      • 如果存在,这意味着我们找到了两个数,它们的和等于 target。返回这两个数的索引(注意索引的顺序)。
      • 如果不存在,将当前元素及其索引存入哈希表中。
    • 如果遍历结束后没有找到结果,可以返回一个空数组或者错误信息,但根据题目描述,我们知道每种输入只会有一个有效答案,所以不会出现这种情况。
    • 代码实现
      class Solution(object):
          def twoSum(self, nums, target):
              """
              使用哈希表解决两个数之和的问题。
              
              :type nums: List[int]
              :param nums: 需要查找的整数数组。
              :type target: int
              :param target: 需要找到的两个整数之和。
              :rtype: List[int]
              :return: 两个数在数组中的下标。
              """
              # 创建一个哈希表,用于存储已经遍历过的元素及其索引
              num_to_index = {}
              
              # 遍历数组中的每个元素
              for i, num in enumerate(nums):
                  # 计算当前元素的补数
                  complement = target - num
                  
                  # 如果补数在哈希表中,返回对应的索引
                  if complement in num_to_index:
                      return [num_to_index[complement], i]
                  
                  # 将当前元素及其索引存入哈希表
                  num_to_index[num] = i
      
              # 如果没有找到解决方案(尽管题目保证只有一个解),可以抛出异常或返回None
              # raise ValueError("No two sum solution found")
              return None

  • 时间复杂度分析:o(n)

5. 题目解析:字母异位词

  • 问题描述

    给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

    字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

    示例 1:

    输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
    输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

    示例 2:

    输入: strs = [""]
    输出: [[""]]
  • 解决方案
    • 算法逻辑
    • 创建一个字典(哈希表),用于将字母排序后的字符串作为键,对应的异位词列表作为值。
    • 遍历字符串数组,对于每个字符串:
      • 将字符串的字母进行排序。
      • 将排序后的字符串作为键,如果该键已存在,则将当前字符串添加到对应的列表中;如果键不存在,则创建新的列表,并将当前字符串加入。
    • 最后,返回字典中的所有列表,这些列表即为所有异位词的分组。
    • 代码实现
      class Solution(object):
          def groupAnagrams(self, strs):
              anagrams = {}
          
              # 遍历字符串数组
              for s in strs:
                  # 对字符串进行排序
                  sorted_str = ''.join(sorted(s))
                  # 如果排序后的字符串已经在字典中,则添加原始字符串
                  if sorted_str in anagrams:
                      anagrams[sorted_str].append(s)
                  else:
                      # 否则,将排序后的字符串和原始字符串添加到字典中
                      anagrams[sorted_str] = [s]
              
              # 从字典中提取所有值,并将它们添加到结果列表中
              return list(anagrams.values())

  • 结果分析

6. 题目解析:最长连续序列

  • 问题描述

    给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

    请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

    示例 1:

    输入:nums = [100,4,200,1,3,2]
    输出:4
    解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
  • 解决方案
    • 算法逻辑
    • 创建一个哈希表 counter 来存储每个数字出现的次数。
    • 初始化 max_length 为 0,用于存储最长连续序列的长度。
    • 遍历数组 nums
      • 对于每个数字,首先检查它是否在 counter 中,如果没有,则添加到 counter 并设置计数为 1。
      • 然后检查 counter 中是否存在该数字减 1 的情况。如果存在,说明可以形成更长的连续序列。
      • 更新 max_length 为当前数字开始的连续序列长度与 max_length 的较大值。
    • 返回 max_length
    • 代码实现
      class Solution(object):
          def longestConsecutive(self, nums):
              if not nums:
                  return 0
              
              num_set = set(nums)  # 将数组转换为集合,提高查找效率
              max_length = 0
              
              for num in num_set:
                  # 如果前一个数字不存在,则从当前数字开始一个新的连续序列
                  if num - 1 not in num_set:
                      current_num = num
                      current_length = 1
                      
                      # 检查后续数字是否存在,延长连续序列
                      while current_num + 1 in num_set:
                          current_num += 1
                          current_length += 1
                      
                      # 更新最大长度
                      max_length = max(max_length, current_length)
              
              return max_length

  • 结果分析

7. 哈希表与其他数据结构的比较

  • 与数组比较

    数组是一种基础的数据结构,提供了通过索引快速访问元素的能力。然而,数组的尺寸通常是固定的,且在数组末尾之外插入或删除元素效率较低。相比之下,哈希表提供了更高的灵活性,允许动态地添加和删除键值对,但在最佳情况下才能提供常数时间的访问效率。

  • 优点:哈希表在动态数据集和需要快速查找的场景下表现更优。
  • 缺点:哈希表可能需要更多的内存,并在处理冲突时可能涉及额外的计算。
  • 与链表比较

    链表是一种线性数据结构,它通过指针连接元素。链表允许在任意位置快速地插入和删除元素,但在查找特定元素时可能需要遍历整个结构。哈希表在查找方面通常更优,但在插入和删除时可能需要重新计算哈希值和调整存储位置。

  • 优点:哈希表在需要频繁查找的场景下提供快速访问。
  • 缺点:链表提供了更好的插入和删除性能,尤其是在已知元素位置的情况下。
  • 与树结构比较

    树结构,如平衡树(例如 AVL 树或红黑树),提供了对数据的有序存储和有效的查找、插入、删除操作,通常具有对数时间复杂度。哈希表在查找方面可能更快,但不保证数据的有序性。

  • 优点:哈希表在数据无序或不需要维护顺序的场景下更优。
  • 缺点:树结构提供了更好的数据组织和范围查询能力,但可能在查找速度上不如哈希表。

8. 哈希表的实际应用案例

  • 数据库索引:在数据库中,哈希表用于创建索引,从而加快数据检索速度。数据库系统使用哈希函数将数据值转换为索引,使得查询操作可以直接访问到数据存储的位置,而无需扫描整个数据表。
  • 缓存系统:缓存系统使用哈希表来存储频繁访问的数据,以减少对原始数据源的访问次数。哈希表提供了快速的数据插入和查找能力,使得缓存系统能够迅速响应请求并提供数据。
  • 推荐系统:推荐系统经常使用哈希表来处理用户兴趣和行为数据。通过哈希表,系统能够快速匹配用户和推荐项,以及跟踪用户与推荐内容的交互历史。哈希表的快速查找和更新能力对于实现实时推荐至关重要。
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值