哈希题目总结

news2024/11/18 19:26:54

以下列举了可以用哈希方法(包括但不限于用HashMap和HashSet)的题目,实质上是把东西丢给这些数据结构去维护。请注意有些题目中用哈希是最优解,有些题目中不是最优解,可以自行探索其时间复杂度和空间复杂度的区别,思考优化的方法(位运算或者原地排序等)。x数之和/差的专题多半都可以用哈希方法。

1 重复元素

1.1、查询/判断是否有重复元素

存在重复元素:给定一个整数数组,判断是否存在重复元素。如果存在一值在数组中出现至少两次,函数返回true。如果数组中每个元素都不相同,则返回false。

 数组中重复的数字:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

class Solution {
    public boolean containsDuplicate(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            if (set.contains(num)) {
                return true;
            }
            set.add(num);
        }
        return false;
    }
}

1.2、判断是否存在重复元素(距离不超过K)

存在重复元素 II:给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引i和j,使得 nums[i] = nums[j],并且i和j的差的绝对值至多为k。

思路:哈希map保存 <num, index>

  • num 重复出现时,更新 index,保证和后面的工作指针更靠近;
class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        //保证了 num再次出现时, index肯定是更靠近工作指针的
        for (int i=0; i<nums.length; i++) {
            if (map.containsKey(nums[i])) {
                if (Math.abs(i - map.get(nums[i])) <= k) {
                    return true;
                }
            }
            map.put(nums[i], i);
        }
        return false;
    }
}

1.3、是否存在重复元素(距离&value差满足一定条件)

存在重复元素 III:在整数数组nums中,是否存在两个下标i 和j,使得nums[i]和nums[j] 的差的绝对值小于等于t,且满足i和j的差的绝对值也小于等于ķ。如果存在则返回true,不存在返回false。

思路:桶

  • 定义 Map
    • key=桶编号;
    • value=具体的num值;
    • map中的数据在 abs(i - j)<=indexDiff 范围内,一旦超过就 remove超出的键值对;
  • 对每个元素 num 计算其对应的桶编号;这题的值域范围限制是[-10^9, 10^9],总数量没有超过有符号整型的正数范围,所以完全可以用更简单的平移法来生成id,避免更多的推导。
  • 检测桶i、i-1、i+1 在map中是否存在,如果存在则自动满足 indexDiff条件,下面判断是否满足valueDiff条件即可
    • 桶 i 内已经存在元素 x,那么 abs(x-num) 肯定满足 valueDiff,返回true;
    • 桶 i-1、i+1 需要额外判断是否满足 abs(x-num)
  • 其他桶就不需要检测了,abs(x-num) 肯定不满足 valueDiff;
  • 如果没找到,就把 num 和桶编号放入到map中;
  • 最后删除不满足 indexDiff的map数据;
class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
        int n = nums.length;
        // key=桶编号, value=具体的num值, map中的数据在 abs(i - j)<=indexDiff 范围内
        Map<Long, Long> map = new HashMap<>();
        //桶大小
        long bucketSize = (long)valueDiff + 1;

        //只要map有值,那么肯定满足 indexDiff的条件,只需要判断 valueDiff的条件即可
        for (int i=0; i<n; i++) {
            //计算元素对应的桶的编号
            long id = getID(nums[i], bucketSize);
            if (map.containsKey(id)) {
                return true;
            }

            //检查相邻的左边桶, 需要满足 abs(nums[i]-nums[j]) <= valueDiff
            if (map.containsKey(id-1) 
                && Math.abs(nums[i] - map.get(id-1)) < bucketSize) {
                return true;
            }
            //检查相邻的右边桶, 需要满足 abs(nums[i]-nums[j]) <= valueDiff
            if (map.containsKey(id+1)
                && Math.abs(nums[i] - map.get(id+1)) < bucketSize) {
                    return true;
            }

            //注意这里肯定不会发生覆盖,因为一旦覆盖就说明两个元素同属一个桶,直接返回true了
            map.put(id, (long)nums[i]);

            //保证map中的数据在 abs(i - j)<=indexDiff 范围内
            if (i >= indexDiff) {
                map.remove(getID(nums[i-indexDiff], bucketSize));
            }
        }
        return false;
    }

    //计算元素所属的桶编号
    private long getID(long x, long bucketSize) {
        //统一正负数
        return (x + 1000000000) / bucketSize;
    }
}

1.4、数组是否存在重复元素(常数空间复杂度&不可修改数组)

寻找重复数:给定一个包含n+1个整数的数组nums,其数字都在1到n之间(包括1和n),可知至少存在一个重复的整数。假设nums只有一个重复的整数,找出这个重复的数。

注意:题目要求不修改原数组 & 常量空间复杂度;

思路:Floyd 判圈算法

找到相遇点:value=6

class Solution {
    public int findDuplicate(int[] nums) {
        //Floyd 判圈算法
        int slow = 0, fast = 0;
        do {
            slow = nums[slow];
            fast = nums[nums[fast]];
        } while (slow != fast);
        //注意此时可能指向的同一个index,而不是不同index的相同value

        slow = 0;
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
}

2 数组交集

两个数组的交集:输出结果中的每个元素一定是唯一的。

两个数组的交集 II:输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。

【提升1】如果给定的数组已经排好序呢?你将如何优化你的算法?

【提升2】如果 nums1 的大小比 nums2 小,哪种方法更优?

【提升3】如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

7.3 数字游戏

  • 珠玑妙算:给定一种颜色组合solution和一个猜测guess,编写一个方法,返回猜中和伪猜中的次数answer,其中answer[0]为猜中的次数,answer[1]为伪猜中的次数。

  • 猜数字游戏:请写出一个根据秘密数字和朋友的猜测数返回提示的函数,返回字符串的格式为xAyB,x和y都是数字,A表示公牛,用B表示奶牛。

  • 有效的数独:判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

  • 分糖果:给定一个偶数长度的数组,其中不同的数字代表着不同种类的糖果,每一个数字代表一个糖果。你需要把这些糖果平均分给一个弟弟和一个妹妹。返回妹妹可以获得的最大糖果的种类数。

  • 扑克牌中的顺子:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为14。

7.4 缓存机制

  • LRU 缓存机制和LRU 缓存-面试题版本:运用你所掌握的数据结构,设计和实现一个LRU (最近最少使用) 缓存机制。学java的同学可以试试基于LinkedHashMap的代码。

  • LFU 缓存:请你为最不经常使用(LFU)缓存算法设计并实现数据结构。

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

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

相关文章

【Java】还不会数组?一文万字全搞定

前言&#xff1a;前面两章我们详细讲解了Java基本程序设计结构中的基本知识&#xff0c;&#xff0c;包括&#xff1a;一个简单的Java应用&#xff0c;注释&#xff0c;数据类型&#xff0c;变量与常量&#xff0c;运算符&#xff0c;字符串&#xff0c;输入输出&#xff0c;控…

探索精酿啤酒:从经典到创新

Fendi club啤酒一直以来都以其卓着的品质和与众不同的口感深受消费者喜爱。而随着时代的变迁和消费者口味的不断变化&#xff0c;Fendi club啤酒也在不断地探索和创新&#xff0c;以满足市场的多样化需求。 在经典的口感和风味基础上&#xff0c;Fendi club啤酒不断地尝试新的原…

多线程学习D10 收尾了应该

线程安全集合类概述 重点介绍java.util.concurrent.* 下的线程安全集合类&#xff0c;可以发现它们有规律&#xff0c;里面包含三类关键词&#xff1a;Blocking、CopyOnWrite、Concurrent Blocking 大部分实现基于锁&#xff0c;并提供用来阻塞的方法 CopyOnWrite 之类容器修改…

探讨关于AutoPSA里CII算法的结构荷载

UKP3D,AutoPDMS导出应力计算文件至管道应力分析软件分析&#xff0c;如下图AutoPSA.用户咨询如图 1.如果计算时考虑水重&#xff0c;把工况中的w改为ww&#xff1b; 2.CAD表格中结构荷载不是单纯的1.5倍&#xff0c;是参照仿GLIF的算法&#xff0c;计算了水重的&#xff08;根…

如何进行资产梳理

前言 为什么要进行资产梳理&#xff1f; 资产梳理方式一: 一、安全防护设备资产 二、对外开放服务项目资产 三、项目外包业务流程资产 资产梳理方式二: 一、业务资源梳理 二、设备资产梳理 三、第三方的服务信息梳理 风险梳理 风险有哪些&#xff1f; 一,账号权限风…

在windows下使用VS Code、CMake、Make进行代码编译

软件环境 Windows11VS CodeNoneCMake3.26.4-windows-x86_64MinGWNone 电脑系统配置 安装MinGW将MinGW安装文件夹中bin文件夹下的mingw32-make.exe复制并重命名为make.exe在文件夹中添加系统路径&#xff0c;具体位置为 系统->系统信息->高级系统设置->高级->环境…

Core_Air724UG学习

产品描述 Core_Air724UG核心板是基于Air724UG cat1模板制作的开发实验板。 该模块支持Lua二次开发或AT指令&#xff0c;方便开发者根据自己的需求灵活选择。 Core_Air724UG核心板专注于小型化&#xff0c;PCB尺寸4246mm&#xff0c;有12x22哥标准2.54mm排针管脚&#xff0c;其…

Android MediaCodec 简明教程(七):使用 MediaCodec 解码到 OES 纹理上

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…

安装oh-my-zsh(命令行工具)

文章目录 一、安装zsh、git、wget二、安装运行脚本1、curl/wget下载2、手动下载 三、切换主题1、编辑配置文件2、切换主题 四、安装插件1、zsh-syntax-highlighting&#xff08;高亮语法错误&#xff09;2、zsh-autosuggestions&#xff08;自动补全&#xff09; 五、更多优化配…

FFmpeg常用命令详解与实战指南

下载地址&#xff1a;Releases BtbN/FFmpeg-Builds (github.com) 1. 获取视频信息 使用FFmpeg获取视频信息是最基本的操作之一。你可以使用-i选项指定输入文件&#xff0c;然后使用FFmpeg内置的分析器来获取视频的各种信息&#xff0c;包括视频编解码器、音频编解码器、分辨…

【bug记录】清除僵尸进程,释放GPU显存

目录 1. 为什么会出现这种情况&#xff1f;2. 解决方案方法一&#xff1a;使用 fuser 命令方法二&#xff1a; 3. 小贴士 在进行深度学习或其他需要GPU支持的任务时&#xff0c;我们有时会发现虽然没有可见的进程在执行&#xff0c;但GPU资源却意外地被占用。这种情况往往会阻碍…

Redis(无中心化集群搭建)

文章目录 1.无中心化集群1.基本介绍2.集群说明 2.基本环境搭建1.部署规划&#xff08;6台服务器&#xff09;2.首先删除上次的rdb和aof文件&#xff08;对之前的三台服务器都操作&#xff09;1.首先分别登录命令行&#xff0c;关闭redis2.清除/root/下的rdb和aof文件3.把上次的…

(23)实时采集微信消息(基于主窗体)-微信UI自动化(.Net+C#)

整理 | 小耕家的喵大仙 出品 | CSDN&#xff08;ID&#xff1a;lichao19897314&#xff09; Q Q | 978124155 往期知识回顾 (1)开启探索微信自动化之路-微信UI自动化(.NetC#) (2)初始化微信窗体UI自动化实例-微信UI自动化(.NetC#) (3)采用热键终止微信采集任务-微信UI自动…

linux调试

文章目录 1. 使用打印来调试1.1 重定向1.2 标准预定义宏1.3 日志代码 2. 内核异常2.1 内核打印2.1.1 打印级别2.1.2 跟踪异常2.1.3 动态打印2.1.4 RAM console 2.2 OOPS2.2.1 有源代码的情况2.2.2 没有源代码的情况 3 查看日志4 工具调试 1. 使用打印来调试 1.1 重定向 2>…

HDLbits 刷题 -- Exams/m2014 q3

Consider the function f shown in the Karnaugh map below. Implement this function. d is dont-care, which means you may choose to output whatever value is convenient. 译&#xff1a;考虑下面卡诺图中显示的函数f。 实现这个函数。D是dont-care&#xff0c;这意味着…

【数据结构】栈(Stack)和队列(Queue)

文章目录 栈一、栈的概念及结构二、栈的特点三、栈的实现1.初始化栈2.判断栈空3.入栈4.出栈5.取栈顶元素6.栈的元素个数7.销毁 队列一、队列的概念及结构二、队列的特点三、队列的实现1.初始化2.入队3.出队4.判断队空5.取队头元素6.取队尾元素 总结 栈 一、栈的概念及结构 栈…

Python ValueError: bad transparency mask

修改前 修复后 运行正常 from PIL import Image# 读取图片 #报错信息解决ValueError: bad transparency mask--相关文档地址https://blog.csdn.net/kalath_aiur/article/details/103945309 #1. 检查 alpha 通道是否是一个有效的掩码。如果不是&#xff0c;则需要对 alpha 通道…

随机梯度下降SGD的理解和现象分析

提出问题&#xff1a;令人疑惑的损失值 在某次瞎炼丹的过程中&#xff0c;出现了如下令人疑惑的损失值变化图像&#xff1a; 嗯&#xff0c;看起来还挺工整&#xff0c;来看看前10轮打印的具体损失值变化&#xff1a; | epoch 1 | iter 5 / 10 | time 1[s] | loss 2.3137 |…

Hadoop3:HDFS的Shell操作(常用命令汇总)

一、简介 什么是HDFS的Shell操作&#xff1f; 很简单&#xff0c;就是在Linux的终端&#xff0c;通过命令来操作HDFS。 如果&#xff0c;你们学习过git、docker、k8s&#xff0c;应该会发现&#xff0c;这些命令的特点和shell命令非常相似 二、常用命令 1、准备工作相关命令…

【VTKExamples::Rendering】第一期 TestAmbientSpheres(环境照明系数)

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例TestAmbientShperes,介绍环境照明系数对Actor颜色的影响,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动…