哈希题目总结

以下列举了可以用哈希方法(包括但不限于用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.mfbz.cn/a/607800.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java入门1.1.1版本

前言&#xff1a; 上面的内容是1.0.0~1.1的内容总结 秉持着先做再定义的理念&#xff0c;这里会带着大家先体验一下类与对象 第一步&#xff1a;新建一个java文件 鼠标右键 → 新建 → 文本文档 → 右键 → 点击重名 → 全选 → hello.java 第二步&#xff1a;用笔记本打开 …

阿里云开发uniapp之uni-starter

一、为什么使用uni-starter uni-starter是集成商用项目常见功能的、云端一体应用快速开发项目模版。 一个应用有很多通用的功能&#xff0c;比如登录注册、个人中心、设置、权限管理、拦截器、banner... uni-starter将这些功能都已经集成好&#xff0c;另外&#xff0c;uni-s…

2023-2024年SaaS行业报告合集(精选22份)

SaaS行业报告/方案&#xff08;精选21份&#xff09; 2023-2024年 报告来源&#xff1a;2023-2024年SaaS行业报告合集&#xff08;精选22份&#xff09; 【以下是资料目录】 2024中国HCM SaaS领导者竞争力持续增强的行业龙头 2024年中国企业级SaaS行业研究报告 2024年SaaS…

基于Transformer网络的多步预测模型

包括完整流程数据代码处理&#xff1a; 多步预测数据集制作、数据加载、模型定义、参数设置、模型训练、模型测试、预测可视化、多步预测、模型评估 ● 环境框架&#xff1a;python 3.9 pytorch 1.8 及其以上版本均可运行 ● 使用对象&#xff1a;论文需求、毕业设计需求者…

Offer必备算法37_记忆化搜索_五道力扣题详解(由易到难)

目录 记忆化搜索概念和使用场景 ①力扣509. 斐波那契数 解析代码1_循环 解析代码2_暴搜递归 解析代码3_记忆化搜索 解析代码4_动态规划 ②力扣62. 不同路径 解析代码1_暴搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 解析代码3_动态规划 ③力扣300. 最…

最详尽的网络安全学习路线!涵盖所有技能点,带你成为网安专家!

目录 零基础小白&#xff0c;到就业&#xff01;入门到入土的网安学习路线&#xff01; 建议的学习顺序&#xff1a; 一、夯实一下基础&#xff0c;梳理和复习 二、HTML与JAVASCRIPT&#xff08;了解一下语法即可&#xff0c;要求不高&#xff09; 三、PHP入门 四、MYSQL…

QX-mini51单片机学习---(4)蜂鸣器

目录 1蜂鸣器工作原理 2三极管工作原理 3本节相关原理图分析 4实践 1蜂鸣器工作原理 2三极管工作原理 我们这里使用PNP三极管&#xff0c;低电压导通 做开关 PNP E&#xff08;emitrer&#xff09;&#xff1a;发射极&#xff0c;B&#xff08;base&#xff09;&#x…

leetcode每日一题第七十二天

class Solution { public:TreeNode* searchBST(TreeNode* root, int val) {if(!root) return root;if(root->val val) return root;else if(root->val > val) return searchBST(root->left,val);else return searchBST(root->right,val);} };

WPF中页面加载时由于TreeView页面卡顿

示例&#xff1a;右侧界面的数据根据左侧TreeView的选项加载不同的数据&#xff0c;页面加载时会把所有的数据加载一遍&#xff0c;导致页面卡顿。 解决办法&#xff1a; <Setter Property"IsSelected" Value"{Binding IsSelected}"/>

初学python记录:力扣1652. 拆炸弹

题目&#xff1a; 你有一个炸弹需要拆除&#xff0c;时间紧迫&#xff01;你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。 为了获得正确的密码&#xff0c;你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 &#xff0c;将第 i 个数字用…

车载测试到底怎么样?真实揭秘!

什么是车载智能系统测试&#xff1f; 车载智能系统&#xff0c;是汽车智能化重要的组成部分&#xff0c;由旧有的车载资通讯系统结合联网汽车技术所演进而来&#xff0c;随着软硬件技术的不断进步&#xff0c; 让车载智能系统拥有强大的运算能力及多元化的应用功能。 车载智能…

FreeRTOS学习 -- 任务相关API函数

一、任务创建和删除API函数 FreeRTOS 最基本的功能就是任务管理&#xff0c;而任务管理最基本的操作就是创建和删除任务。 FreeRTOS的任务创建和删除API函数如下&#xff1a; 1、函数 xTaskCreate() 此函数用来创建一个任务&#xff0c;任务需要 RAM 来保存于任务有关的状…

【C语言项目】贪吃蛇(上)

个人主页 ~ gitee仓库~ 欢迎大家来到C语言系列的最后一个篇章–贪吃蛇游戏的实现&#xff0c;当我们实现了贪吃蛇之后&#xff0c;我们的C语言就算是登堂入室了&#xff0c;基本会使用了&#xff0c;当然&#xff0c;想要更加熟练地使用还需要多多练习 贪吃蛇 一、目标二、需要…

Windows远程桌面实现之十四:实现AirPlay接收端,让苹果设备(iOS,iPad等)屏幕镜像到PC端

by fanxiushu 2024-05-04 转载或引用请注明原始作者。 这个课题已经持续了好几年&#xff0c;已经可以说是很长时间了。 实现的程序是 xdisp_virt&#xff0c; 可以去github下载使用:GitHub - fanxiushu/xdisp_virt: xfsredir file system 一开始是基于测试镜像驱动的目的随便开…

【Android】Kotlin学习之数据容器(数组创建)

kotlin数组 数组是一种初始化时指定容器大小, 不可以动态调整其大小的容器 数组创建

C++数据类型与表达式

一 C中的数据类型 二 基本数据类型 三 类型转换 各种类型的高低顺序如下所述; 四 构造数据类型 类类型

MYSQL-8.调优

性能优化思维 整体思维 木桶效应&#xff1a;系统的性能符合木桶效应&#xff08;一个木桶能装多少水&#xff0c;取决于木桶中最短的那块木板&#xff09;&#xff0c;所以性能优化需要从多个方面去考虑&#xff0c;如架构优化、业务优化、前端优化、中间件调优、网关优化、…

21物联1班常用网络命令

常用网络命令 ipconfig&#xff08;配置&#xff09;ping(测试)命令1&#xff1a;ping 172.16.0.12&#xff1a;ping ip -t3&#xff1a;ping ip -l 3000&#xff08;注意每个之间都存在空格&#xff09;4&#xff1a;ping ip -n count netstat&#xff08;网络&#xff09;命令…

初识C语言——第十六天

C语言中的语句结构类型:顺序/选择/循环 分支语句 if else switch 循环语句 while for do whlie goto语句 代码练习:找两个整数的最大公约数和最小公倍数 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h>//int main() //{ // int age 60; // if (ag…

探索智能编程新境界:我与Baidu Comate的独特体验之旅

文章目录 一、认识Baidu Comate二、VS Code安装Baidu Comate教程三、Baidu Comate功能体验功能概览具体功能1.根据注释自动生成代码2.函数注释3.行间注释4.代码解释5.生成单元测试6.代码优化7.答疑解惑 四、交互体验五、总结 一、认识Baidu Comate ✨Baidu Comate插件是一款基…