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

【练习】哈希表的使用

  • 🎥 个人主页:Dikz12
  • 🔥个人专栏:算法(Java)
  • 📕格言:吾愚多不敏,而愿加学
  • 欢迎大家👍点赞✍评论⭐收藏

目录

1.哈希表简介 

2.两数之和

题目描述

题解

代码实现

2.面试题.判定是否互为字符重排

题目描述 

题解 

代码实现 

3.存在重复元素

题目描述 

题解 

代码实现 

4.存在重复元素 II

题目描述 

题解 

代码实现 

5.字母异位词分组

题目描述 

题解 

代码实现 


1.哈希表简介 

  • 哈希表是什么?

存储数据的容器。

  • 有什么用 ?

快速查找某个元素,时间复杂度可以达到 O(1)。 

  • 什么时候用哈希表? 

当出现频繁查找某一个数的场景时。 

  • 怎么用哈希表? 

1.容器(哈希表 HashMap)

2.用数组模拟简易的哈希表。如:字符串中的字符,数据范围很小的时候。 

2.两数之和

题目描述

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

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

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

示例 1:

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

题解

 解法一:暴力枚举.  O(n^2)

  1. 先固定其中一个数.
  2.  依次与该数之前的数相加.

解法二: 使用哈希表来优化.  O(n)

  • 可以事先将「数组内的元素」和「下标」绑定在⼀起存⼊「哈希表」中,然后直接在哈希表中查找每⼀个元素的 target - nums[i] ,就能快速的找到⽬标和的下标.
  • 这⾥有⼀个⼩技巧,可以不⽤将元素全部放⼊到哈希表之后,再来⼆次遍历;⽽是在将元素放⼊到哈希表中的同时,直接来检查表中是否已经存在当前元素所对应的⽬标元素(即 target - nums[i] )。                                                                                                                              

代码实现

    public int[] twoSum(int[] nums, int target) {//<value, i>Map<Integer, Integer> hash = new HashMap<>();for(int i = 0; i < nums.length; i++) {int ret = target - nums[i];if(hash.containsKey(ret)) {return new int[]{i, hash.get(ret)};}hash.put(nums[i], i);}return new int[]{-1, -1};}

2.面试题.判定是否互为字符重排

题目描述 

题解 

解法:使用哈希表. 

算法思路:
  1. 当两个字符串的⻓度不相等的时候,是不可能构成互相重排的,直接返回 false
  2. 如果两个字符串能够构成互相重排,那么每个字符串中各个字符出现的次数⼀定是相同 的。因此,我们可以分别统计出这两个字符串中各个字符出现的次数,然后逐个⽐较是否相等即可。这样的话,我们就可以选择「哈希表」来统计字符串中字符出现的次数。

代码实现 

    public boolean CheckPermutation(String s1, String s2) {if(s1.length() != s2.length()) {return false;}int[] hash = new int[26];//先把第一个字符串信息统计到哈希表中for(int i = 0; i < s1.length(); i++) {hash[s1.charAt(i) - 'a']++;}for(int j = 0; j < s2.length(); j++) {hash[s2.charAt(j) - 'a']--;if(hash[s2.charAt(j) - 'a'] < 0) {return false;}}return true;}

3.存在重复元素

题目描述 

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

示例 1:

输入:nums = [1,2,3,1]
输出:true

示例 2:

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

题解 

算法思路:(和两数之和的逻辑一样)

  • 仅需在遍历数组的过程中,检查当前元素「是否在之前已经出现过」即可。  
  • 可以利⽤哈希表,仅需存储数「组内的元素」。在遍历数组的时候,⼀边检查哈希表中是否
    已经出现过当前元素,⼀边将元素加⼊到 哈希表中。

代码实现 

    public boolean containsDuplicate(int[] nums) {Set<Integer> hash = new HashSet<>();for(int i = 0; i < nums.length; i++) {if(hash.contains(nums[i])) {return true;}hash.add(nums[i]);}return false;}

4.存在重复元素 II

题目描述 

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [1,2,3,1], k = 3
输出:true

示例 3:

输入:nums = [1,2,3,1,2,3], k = 2
输出:false

题解 

算法思路:
解决该问题需要我们快速定位到两个信息:
  • 两个相同的元素;
  • 这两个相同元素的下标。
因此,我们可以使⽤「哈希表」,令数组内的元素做 key 值,该元素所对应的下标做 val 值,将
「数组元素」和「下标」绑定在⼀起,存⼊到「哈希表」中。

代码实现 

    public boolean containsNearbyDuplicate(int[] nums, int k) {Map<Integer, Integer> hash = new HashMap<>();for(int i = 0; i < nums.length; i++) {if(hash.containsKey(nums[i])) {int ret = hash.get(nums[i]);if(i - ret <= k) {return true;}}hash.put(nums[i], i);}return false;}

5.字母异位词分组

题目描述 

题解 

算法思路:
互为字⺟异位词的单词有⼀个特点:将它们 排序 之后,两个单词应该是 完全相同 的。 所以,我们可以利⽤这个特性,将单词按照字典序排序,如果排序后的单词相同的话,就划分到同⼀ 组中。
利⽤语⾔提供的「容器」的强⼤的功能就能实现这两点:
  • 将排序后的字符串( string )当做哈希表的 key 值;
  • 将字⺟异位词数组( string[] )当成 val 值。

代码实现 

    public List<List<String>> groupAnagrams(String[] strs) {Map<String, List<String>> hash = new HashMap<>();for(String s : strs) {char[] tmp = s.toCharArray();//排序Arrays.sort(tmp);String key = new String(tmp);//哈希表中不存在if(!hash.containsKey(key)) {hash.put(key, new ArrayList());}//存在hash.get(key).add(s);}//提取结果return new ArrayList(hash.values());}

相关文章:

  • Python切片技巧,带你轻松提取数组子集!
  • NeRF笔记
  • SpringBoot 基于iText 根据PDF模板动态生成文件
  • OSError: [E050] Can‘t find model ‘en_core_web_sm‘.
  • Python爬虫(一文通)
  • OverflowError: cannot convert float infinity to integer
  • Golang使用Quic-Go开源库实现Quic客户端和服务端
  • 企业数据治理之主数据---供应商主数据
  • Java核心API——io类缓冲流
  • 什么是杨氏模量
  • 22AP10 SS524 平替 海思HI3521DV200 可提供开发资料
  • IP-RDS-222、IP-PRZ-59-AM12、EG-TRZ-42-L、EG-TRZ-42-H比例减压阀放大器
  • Qt详解QHostInfo
  • 【python报错已解决】AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘
  • 对标GPT4o,智谱推出新一代基座大模型 GLM-4-Plus
  • Android框架之Volley
  • CSS盒模型深入
  • fetch 从初识到应用
  • gops —— Go 程序诊断分析工具
  • Java 23种设计模式 之单例模式 7种实现方式
  • js对象的深浅拷贝
  • Netty源码解析1-Buffer
  • Node 版本管理
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 从零开始学习部署
  • 批量截取pdf文件
  • 浅谈Golang中select的用法
  • 再谈express与koa的对比
  • 走向全栈之MongoDB的使用
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (C语言)二分查找 超详细
  • (C语言)逆序输出字符串
  • (javascript)再说document.body.scrollTop的使用问题
  • (STM32笔记)九、RCC时钟树与时钟 第一部分
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (黑马C++)L06 重载与继承
  • (九)One-Wire总线-DS18B20
  • (篇九)MySQL常用内置函数
  • (四) 虚拟摄像头vivi体验
  • (四)React组件、useState、组件样式
  • (四)进入MySQL 【事务】
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (译)2019年前端性能优化清单 — 下篇
  • (转)程序员技术练级攻略
  • ./和../以及/和~之间的区别
  • .NET Remoting学习笔记(三)信道
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .NET业务框架的构建
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • .考试倒计时43天!来提分啦!
  • @Autowired标签与 @Resource标签 的区别
  • [] 与 [[]], -gt 与 > 的比较