算法题学习笔记-哈希

1 哈希

哈希是一种常见的算法。哈希表(Hash Table)也称为散列表,是一种数据结构,它使用哈希函数将键映射到数组的索引上,以便快速查找和插入数据。哈希表通常用于实现关联数组和集合,以实现高效的查找、插入和删除操作。
返回面试宝典目录

2 算法题

这里借用力扣官网的算法题进行举例说明哈希表的使用。

2.1 两数之和

给定一个整数数组 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
只会存在一个有效答案

2.1.1 题解

注意到方法一的时间复杂度较高的原因是寻找 target - x 的时间复杂度过高。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。

使用哈希表,可以将寻找 target - x 的时间复杂度降低到从 O(N) 降低到 O(1)。

这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。

2.1.2 程序示例

    /*** 两位数之和*/public int[] twoSum(int[] nums, int target) {Map<Integer, Integer> hashtable = new HashMap<>();for (int i = 0; i < nums.length; ++i) {if (hashtable.containsKey(target - nums[i])) {return new int[]{hashtable.get(target - nums[i]), i};}hashtable.put(nums[i], i);}return new int[0];}

2.2 字母异位词分组

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

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

示例 1:输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:输入: strs = [""]
输出: [[""]]
示例 3:输入: strs = ["a"]
输出: [["a"]]
提示:1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] 仅包含小写字母

2.2.1 题解

由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键。

2.2.2 程序示例

	/*** 字母异位词分组*/public List<List<String>> groupAnagrams(String[] strs) {Map<String, List<String>> hashMap = new HashMap<>();for (String c : strs) {char[] chars = c.toCharArray();Arrays.sort(chars);String key = Arrays.toString(chars);if (!hashMap.containsKey(key)) {hashMap.put(key, new ArrayList<String>());}hashMap.get(key).add(c);}return new ArrayList<>(hashMap.values());}

2.3 最长连续序列

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

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

示例 1:输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9
提示:0 <= nums.length <= 105
-109 <= nums[i] <= 109

2.3.1 题解

我们考虑枚举数组中的每个数 x,考虑以其为起点,不断尝试匹配 x+1,x+2,⋯ 是否存在,假设最长匹配到了 x+y,那么以 x 为起点的最长连续序列即为 x,x+1,x+2,⋯ ,x+y,其长度为 y+1,我们不断枚举并更新答案即可。

对于匹配的过程,暴力的方法是 O(n) 遍历数组去看是否存在这个数,但其实更高效的方法是用一个哈希表存储数组中的数,这样查看一个数是否存在即能优化至 O(1 的时间复杂度。

仅仅是这样我们的算法时间复杂度最坏情况下还是会达到 O(n^2)
)(即外层需要枚举 O(n)个数,内层需要暴力匹配 O(n) 次),无法满足题目的要求。但仔细分析这个过程,我们会发现其中执行了很多不必要的枚举,如果已知有一个 x,x+1,x+2,⋯ ,x+y的连续序列,而我们却重新从 x+1,x+2 或者是 x+y处开始尝试匹配,那么得到的结果肯定不会优于枚举 x 为起点的答案,因此我们在外层循环的时候碰到这种情况跳过即可。

那么怎么判断是否跳过呢?由于我们要枚举的数 x 一定是在数组中不存在前驱数 x−1 的,不然按照上面的分析我们会从 x−1开始尝试匹配,因此我们每次在哈希表中检查是否存在 x−1即能判断是否需要跳过了。

2.3.2 程序示例

    /*** 最长连续序列*/public int longestConsecutive(int[] nums) {Set<Integer> numsSet = new HashSet<>();for (int num : nums) {numsSet.add(num);}int longestStreak = 0;for (int num : nums) {if (!numsSet.contains(num - 1)) {int currentStreak = 1;int currentNum = num;while (numsSet.contains(currentNum + 1)) {currentNum += 1;currentStreak += 1;}longestStreak = Math.max(longestStreak, currentStreak);}}return longestStreak;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/638776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker常用基础命令

文章目录 1、Docker 环境信息命令1.1、docker info1.2、docker version 2、系统日志信息常用命令2.1、docker events2.2、docker logs2.3、docker history 3、容器的生命周期管理命令3.1、docker create3.2、docker run 总结 1、Docker 环境信息命令 1.1、docker info 显示 D…

Linux 命令大全 CentOS常用运维命令

文章目录 1、Linux 目录结构2、解释目录3、命令详解3.1、shutdown命令3.1、文件目录管理命令ls 命令cd 命令pwd 命令tree 命令mkdir 命令touch 命令cat 命令cp 命令more 命令less 命令head 命令mv 命令rm 命令ln 命令tail 命令cut命令 3.2、用户管理useradd/userdel 命令用户的…

使用残差网络识别手写数字及MNIST 数据集介绍

MNIST 数据集已经是一个几乎每个初学者都会接触的数据集, 很多实验、很多模型都会以MNIST 数据集作为训练对象, 不过有些人可能对它还不是很了解, 那么今天我们一起来学习一下MNIST 数据集。 1.MNIST 介绍 MNIST 数据集来自美国国家标准与技术研究所, National Institute of S…

2. SpringBoot3 实战之用户模块接口开发

文章目录 开发模式和环境搭建开发模式环境搭建 1. 用户注册1.1 注册接口基本代码编写1.2 注册接口参数校验 2. 用户登录2.1 登录接口基本代码编写2.2 登录认证2.2.1 登录认证引入2.2.2 JWT 简介2.2.3 登录功能集成 JWT2.2.4 拦截器 3. 获取用户详细信息3.1 获取用户详细信息基本…

openEuler安装KVM

1、关闭防火墙和selinux [rootlocalhost ~]# systemctl stop firewalld[rootlocalhost ~]# setenforce 0 2、下载软件包 libvirt&#xff1a;用于管理虚拟化平台的开源的 API&#xff0c;后台程序和管理工具。 qemu&#xff1a;开源&#xff08;模拟&#xff09;软件&#…

【MySQL】InnoDB 什么情况下会产生死锁

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;数据库 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 结语 我的其他博客 前言 在数据库管理系统中&#xff0c;特别是使用 InnoDB 存储引擎的 MySQL 中&#xff0c;死锁是一个可能影响…

Win10下在Qt项目中配置SQlite3环境

资源下载 官网资源&#xff1a;SQLite Download Page 1、sqlite.h sqlite-amalgamation-3450000.zip (2.60 MiB) 2、sqlite3.def&#xff0c;sqlite3.dll sqlite-dll-win-x64-3450000.zip (1.25 MiB) 3、 win10下安装sqlite3所需要文件 sqlite-tools-win-x64-3450000.zipht…

java基础02-装箱和拆箱

装箱和拆箱 Java中的装箱和拆箱是指将基本数据类型和对应的包装类之间的转换过程。 1.装箱是将基本数据类型转换为对应的包装类类型的过程。 例如&#xff0c;将int类型转换为Integer类型。在Java中&#xff0c;可以使用自动装箱和强制装箱来实现装箱操作。自动装箱是编译器自…

SpringBoot工程Maven构建引用本地jar包依赖

目前大部分项目使用了SpringBoot&#xff0c;在项目实施过程中可能遇到没有搭建私有仓库&#xff0c;并且需要引入第三方提供的jar包&#xff08;例如某些SDK&#xff09;的情况。一般遇到以上情况可以将第三方提供的jar包通过以下命令安装到本地仓库&#xff0c;然后本地进行构…

万界星空科技MES系统的生产管理流程

对于生产型工厂来说&#xff0c;车间生产流程无疑是最重要的管理环节&#xff0c;繁琐的生产细节让企业很难找到合理的生产管理方法&#xff0c;导致人工效率低、错误多、成本高。如果想要解决这些问题&#xff0c;工厂就必须要有一套自己的生产管理系统&#xff0c;这样才能提…

【Leetcode】410. 分割数组的最大值

文章目录 题目思路1.max_element2.partial_sum3.upper_bound4.distance 代码运行结果 题目 题目链接 给定一个非负整数数组 nums 和一个整数 k &#xff0c;你需要将这个数组分成 k 个非空的连续子数组。 设计一个算法使得这 k 个子数组各自和的最大值最小。 示例1&#xff1…

玩转 SpEL 表达式

本文概览 欢迎阅读本文&#xff0c;其中我们将深入探讨 Spring Expression Language&#xff08;SpEL&#xff09;的语法和实际应用。从基础概念到高级用法&#xff0c;我们将在本文中了解如何使用 SpEL 提高代码的灵活性和表达力。无论大家是初学者还是有经验的开发者&#x…

ACM题解Day2|1.台风, 2.式神考试,3.DNA,4.方程求解

学习目标&#xff1a; 博主介绍: 27dCnc 专题 : 数据结构帮助小白快速入门 &#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d;&#x1f44d; ☆*: .&#xff61;. o(≧▽≦)…

Python 算法交易实验67 第一次迭代总结

说明 在这里对第一次迭代&#xff08;2023.7~ 2024.1&#xff09;进行一些回顾和总结&#xff1a; 回顾&#xff1a; 1 实现了0~1的变化2 在信息隔绝的条件下&#xff0c;无控制的操作&#xff0c;导致被套 总结&#xff1a; 思路可行&#xff0c;在春暖花开的时候&#x…

企业Oracle1 数据库管理

Oracle的安装 一、基础表的创建 1.1 切换到scott用户 用sys 账户 登录 解锁scott账户 alter user scott account unlock;conn scott/tiger;发现并不存在scott账户&#xff0c;自己创建一个&#xff1f; 查找资料后发现&#xff0c;scott用户的脚本需要自己执行一下 C:\ap…

三、MySQL库表操作

3.1 SQL语句基础&#xff08;SQL命令&#xff09; 3.1.1 SQL简介 SQL&#xff1a;结构化查询语言(Structured Query Language)&#xff0c;在关系型数据库上执行数据操作&#xff0c;数据检索以及数据维护的标准化语言。使用SQL语句&#xff0c;程序员和数据库管理员可以完成…

Opncv模板匹配 单模板匹配 多模板匹配

目录 问题引入 单模板匹配 ①模板匹配函数: ②查找最值和极值的坐标和值: 整体流程原理介绍 实例代码介绍: 多模板匹配 ①定义阈值 ②zip函数 整体流程原理介绍 实例代码: 问题引入 下面有请我们的陶大郎登场 这张图片是我们的陶大郎,我们接下来将利用陶大郎来介绍…

stm32h7中RTC的BCD模式与BIN模式

RTC的BCD格式与BIN格式 BCD&#xff08;Binary-Coded Decimal&#xff09;和BIN&#xff08;Binary&#xff09;是两种不同的数字表示格式。 BCD格式&#xff1a; BCD是一种用二进制编码表示十进制数字的格式。在BCD格式中&#xff0c;每个十进制数位使用4位二进制数来表示&am…

c++程序的内存模型,new操作符详解

目录 内存四区 程序运行前 代码区 全局区 程序运行后 栈区 堆区 new操作符 创建一个数 创建一个数组 内存四区 不同区域存放不同的数据&#xff0c;赋予不同的生命周期&#xff0c;让我们更加灵活的编程 程序运行前 程序运行前就有代码区和全局区 代码区 程序编…

Windows系统下使用docker-compose安装mysql8和mysql5.7

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7 文章目录 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7MySQL81.新建文件夹2.创建…