当前位置: 首页 > news >正文

注册网站商标长垣网站建设

注册网站商标,长垣网站建设,采集电影做的网站,重庆建站模板搭建1. 算法思想 在算法题中,哈希表(Hash Table)的核心作用是高效存储和快速查找键值对,其算法思想可总结为以下几点: 1. 快速判断元素是否存在 适用场景:需要判断某个元素是否在集合中,或统计元…

1. 算法思想

在算法题中,哈希表(Hash Table)的核心作用是高效存储和快速查找键值对,其算法思想可总结为以下几点:

1. 快速判断元素是否存在

  • 适用场景:需要判断某个元素是否在集合中,或统计元素出现次数。
  • 核心思路:用哈希表记录元素的存在性或频率,将原本 \(O(n)\) 的遍历查找优化为 \(O(1)\) 的哈希表查询。
  • 典型例题:两数之和、存在重复元素、字母异位词判断。

2. 分组与映射

  • 适用场景:将具有相同特征的元素归为一组(如字母异位词、同构字符串)。
  • 核心思路:设计哈希表的键为元素的特征(如排序后的字符串、字符频率数组),值为符合该特征的元素集合。
  • 典型例题:字母异位词分组、有效的字母异位词。

3. 缓存中间结果

  • 适用场景:避免重复计算,保存子问题的解(如动态规划中的重叠子问题)。
  • 核心思路:用哈希表记录已计算的结果,下次需要时直接查询,减少时间复杂度。
  • 典型例题:斐波那契数列、爬楼梯问题的优化。

4. 处理冲突与滑动窗口

  • 适用场景:在限定范围(如长度为 k 的窗口)内统计元素频率或判断重复。
  • 核心思路:结合哈希表与滑动窗口,动态维护窗口内的元素状态,通过哈希表快速检查窗口内是否存在目标元素。
  • 典型例题:存在重复元素 II、无重复字符的最长子串。

5. 双向映射与关系记录

  • 适用场景:需要维护两个变量之间的双向关联(如字符替换、模式匹配)。
  • 核心思路:使用两个哈希表分别记录正向和反向映射关系,确保映射的唯一性。
  • 典型例题:同构字符串、单词规律。

6. 空间换时间

  • 本质:哈希表通过额外的存储空间,将时间复杂度从 \(O(n)\) 或 \(O(n^2)\) 优化到 \(O(1)\) 或 \(O(n)\)。
  • 注意事项:需权衡空间复杂度,避免过度使用导致内存溢出(如哈希表存储整个数组的元素)。

解题步骤总结

  1. 分析问题:判断是否需要快速查找、去重、分组或缓存结果。
  2. 设计键值映射:确定哈希表的键(如元素值、排序后的字符串、频率数组)和值(如元素索引、出现次数、元素集合)。
  3. 处理冲突逻辑:根据题意选择合适的冲突处理方式(如直接覆盖、链表存储)。
  4. 优化与边界检查:考虑动态扩容、滑动窗口维护、空值或重复元素的特殊处理。

2. 例题

2.1 两数之和

1. 两数之和 - 力扣(LeetCode)

 

这是经典 “两数之和” 问题的解法,核心思路如下:

1. 利用哈希表优化查找

用 unordered_map(哈希表)存储数组元素值和对应的下标 。遍历数组时,通过哈希表快速判断 target - 当前元素 是否存在,将原本暴力枚举两层循环的 \(O(n^2)\) 时间复杂度,优化为 \(O(n)\) (n 是数组长度 )。

2. 遍历 + 查找的流程

  • 遍历数组 nums ,对每个元素 nums[i]
    • 计算差值 comp = target - nums[i] ,查哈希表是否有 comp 。
    • 若有,说明找到两个数(comp 对应数和 nums[i] ),返回它们的下标 {hash[comp], i} 。
    • 若没有,把当前元素 nums[i] 和下标 i 存入哈希表,继续遍历。

这样一趟遍历就能完成查找,高效解决问题,本质是用空间换时间,靠哈希表快速查询特性简化流程。

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hash;for(int i = 0; i < nums.size(); ++i){if(hash.count(target - nums[i])) return {hash[target - nums[i]], i};hash[nums[i]] = i;}return {};}
};

 

2.2 面试题 01.02. 判定是否为字符重排

面试题 01.02. 判定是否互为字符重排 - 力扣(LeetCode)

核心思路如下:

1. 预处理:检查长度是否相等

  • 如果 s1 和 s2 的长度不同,直接返回 false。因为变位词必须由完全相同的字符组成,长度必然相等。

2. 统计字符频率

  • 使用一个长度为 26 的数组 hash 统计 小写字母 的出现次数(假设输入仅含小写字母)。
  • 遍历 s1,将每个字符 ch 映射到数组下标 ch - 'a',并增加对应计数。

3. 验证字符频率匹配

  • 遍历 s2,对每个字符 ch
    • 如果 hash[ch - 'a'] > 0,说明 s1 中存在该字符,将计数减一。
    • 如果 hash[ch - 'a'] == 0,说明 s2 中的该字符在 s1 中不存在或已被用完,直接返回 false

4. 返回结果

  • 如果遍历完 s2 所有字符都没有提前返回 false,说明 s1 和 s2 的字符频率完全一致,返回 true

关键点

  • 时间复杂度:\(O(n)\),其中 n 是字符串长度。两次遍历数组即可完成判断。
  • 空间复杂度:\(O(1)\),因为数组长度固定为 26,不随输入规模变化。
  • 适用条件:输入字符串仅含小写字母。若包含其他字符(如大写字母、数字),需扩大数组范围或改用哈希表。

 

class Solution {
public:bool CheckPermutation(string s1, string s2) {if(s1.size() != s2.size()) return false;int hash[26];for(auto ch : s1) ++hash[ch - 'a'];for(auto ch : s2) if(hash[ch - 'a'] > 0) --hash[ch - 'a'];else return false;return true;}
};

 

2.3 存在重复元素

217. 存在重复元素 - 力扣(LeetCode)

核心思路如下:

1. 利用哈希表记录元素出现次数

  • 使用 unordered_map<int, int>(哈希表)统计每个元素的出现次数。
  • :数组中的元素值;:该元素出现的次数。

2. 遍历数组,检查重复

  • 遍历数组 nums,对每个元素 n
    • 检查哈希表:如果 n 已存在(即 hash.count(n) > 0),说明该元素是重复的,直接返回 true
    • 记录元素:若 n 不存在,将其加入哈希表并计数为 1(即 ++hash[n])。

3. 返回结果

  • 如果遍历完整个数组都没有发现重复元素,返回 false

关键点

  • 时间复杂度:\(O(n)\),其中 n 是数组长度。遍历一次数组,哈希表的插入和查找操作平均时间为 \(O(1)\)。
  • 空间复杂度:\(O(n)\),最坏情况下数组所有元素都不同,需存储整个数组的元素。
  • 哈希表的选择:使用 unordered_map 而非 map 是因为前者基于哈希表实现,查找效率更高(平均 \(O(1)\) vs. 红黑树的 \(O(\log n)\))。

 

class Solution {
public:bool containsDuplicate(vector<int>& nums) {unordered_map<int, int> hash;for(auto n : nums){if(hash.count(n)) return true;else ++hash[n];}return false;}
};

 

2.4 存在重复元素 2

219. 存在重复元素 II - 力扣(LeetCode)

核心思路如下:

1. 问题理解

判断数组中是否存在重复元素,且它们的下标之差不超过给定值 k。 例如:nums = [1,2,3,1]k = 3,下标 0 和 3 的元素均为 1,差值 3 ≤ 3,返回 true

2. 哈希表维护元素的最新下标

  • 使用 unordered_map<int, int> 记录每个元素最近一次出现的下标
  • :元素值;:该元素在数组中的最新下标。

3. 遍历数组,检查条件

  • 遍历数组 nums,对每个元素 nums[i]
    1. 检查重复:若哈希表中已存在 nums[i],计算当前下标 i 与上次下标 hash[nums[i]] 的差值。
      • 若差值 ≤ k,说明存在满足条件的重复元素,返回 true
    2. 更新哈希表:将当前元素的下标 i 存入哈希表(覆盖旧值),确保记录的是最新位置。

4. 返回结果

  • 若遍历结束仍未找到符合条件的重复元素,返回 false

关键点

  • 时间复杂度:\(O(n)\),一次遍历数组,哈希表操作平均 \(O(1)\)。
  • 空间复杂度:\(O(n)\),最坏情况下需存储所有元素的下标。
  • 滑动窗口思想:通过哈希表动态维护元素的最新位置,等价于在长度为 k 的滑动窗口内检查重复。

 

class Solution {
public:bool containsNearbyDuplicate(vector<int>& nums, int k) {unordered_map<int, int> hash;for(int i = 0; i < nums.size(); ++i){if(hash.count(nums[i]) && abs(hash[nums[i]] - i) <= k)return true;hash[nums[i]] = i;}return false;}
};

 

2.5 字母移位次分组

49. 字母异位词分组 - 力扣(LeetCode)

核心思路如下:

1. 问题理解

将字符串数组中的字母异位词(由相同字母重排列形成的字符串)分为一组。 例如:strs = ["eat", "tea", "tan", "ate"] → [["eat","tea","ate"],["tan"]]

2. 哈希表映射:排序后的字符串 → 原字符串列表

  • 关键观察:字母异位词排序后得到的字符串相同(如 "eat" 和 "tea" 排序后均为 "aet")。
  • 使用 unordered_map<string, vector<string>> 记录:
    • :排序后的字符串(如 "aet")。
    • :所有排序后等于该键的原字符串列表(如 ["eat", "tea", "ate"])。

3. 遍历字符串数组,构建哈希表

  • 对每个字符串 s
    1. 生成键:复制 s 为 tmp 并排序,得到 tmp(如 "eat" → "aet")。
    2. 分组:将 s 加入哈希表中 tmp 对应的列表(如 hash["aet"].push_back("eat"))。

4. 提取结果

  • 遍历哈希表,将每个键对应的字符串列表(vector<string>)收集到结果 ret 中。

关键点

  • 时间复杂度:\(O(n \cdot k \log k)\),其中 n 是字符串数量,k 是字符串的最大长度(每个字符串排序时间为 \(O(k \log k)\))。
  • 空间复杂度:\(O(n \cdot k)\),存储所有字符串及其排序后的键。
  • 扩展性:若输入含非小写字母(如大写字母或数字),排序逻辑需调整(如使用计数排序生成键)。

 

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {vector<vector<string>> ret;unordered_map<string, vector<string>> hash;for(auto s : strs){string tmp = s;sort(tmp.begin(), tmp.end());hash[tmp].push_back(s);}for(auto& [x, y] : hash)ret.push_back(y);return ret;}
};

 

http://www.dtcms.com/a/438934.html

相关文章:

  • 栈的压入弹出序列--牛客
  • 深圳设计网站南宁专业做网站
  • 同ip网站有什么危害不动产网站建设
  • 卫星通信天线极化角偏差对天线增益、交叉极化隔离度的影响
  • 好用的ppt模板网站公司网站建设费会计分录
  • Day92 基本情报技术者 单词表28 AI応用
  • 蛋糕店网站开发策划书公司网站优点
  • 网络卖东西的平台有哪些公司网站优化推广
  • 2025 AI 治理困局:假新闻围剿与隐私保护的双重博弈
  • 一个RCE命令执行靶场,包含基础命令、shell 特性、常见姿势、常见waf绕过
  • 受欢迎的福州网站建设wordpress后台模块
  • 李宏毅-Generative AI-第一课
  • 服务器安装完面板怎么做网站免费h5页面制作app
  • datawhale RAG技术全栈指南 202509 第5次作业
  • 怎么屏蔽ip段访问网站哪个做网站好
  • 手机电商网站 模板工程信息建程网
  • 找人做网站 自己购买服务器图片链接生成器软件
  • Day94 基本情报技术者 单词表30 ビッグデータ応用
  • 基于华为openEuler部署uptime-kuma监控面板
  • 数据库表设计通用规范:从基础命名到性能优化
  • The “How” (续) - 研发团队如何运转一次良好的迭代Sprint
  • 南通企业免费建站泗阳网页定制
  • 如何做中英文切换的双语网站东莞长安网站设计
  • 用html制作网站代码申请域名邮箱
  • 调和函数在球上的平均值性质与Poisson公式估计
  • Spring——声明式事务
  • 【Go 语言】揭秘 Go 语言的并发魔法:Goroutine 入门指南
  • 工商企业信息查询网站深圳宝安龙岗紧急寻人
  • 怎么上传视频到公司网站西安seo排名扣费
  • cms(网站内容管理系统)有哪些商业信息网站大全