set,map(java)

前言:要了解set和map,首先需要对搜索树和哈希有一定的了解,才能进一步深入的了解set和map。

1.搜索树

(1)性质:

若它的左子树不为空,则左子树上所有节点值都小于根节点的值。

若它的右子树不为空,则右子树上所有节点值都大于根节点的值。

它的左右子树也分别为二叉搜索树。

二叉搜索树中不允许出现相同的值

eg:

(2)相关功能的实现:

前提得实现一个节点类TreeNode,包含left(左子树),right(右子树),val三个属性。

a.查找:

分析:

时间复杂度:

最好情况:O(\log_{2}N)

最坏情况:O(N) 

代码实现:

public TreeNode search(int val) {if(root == null) {return null;}TreeNode cur = root;while(cur != null) {if (cur.val > val) {//进到左边cur = cur.left;} else if (cur.val < val) {//进到右边cur = cur.right;} else {return cur;}}return null;
}

b.插入:

分析:

时间复杂度与查找的相同。

代码实现:

public void insert(int val) {if(root == null) {root = new TreeNode(val);return;}TreeNode node = new TreeNode(val);TreeNode cur = root;TreeNode parent = null;while(cur != null) {parent = cur;if (cur.val > node.val) {//进到左边cur = cur.left;} else if (cur.val < node.val) {//进到右边cur = cur.right;} else {return;}}//记录父亲节点的用处if(parent.val > node.val) {parent.left = node;}if(parent.val < node.val) {parent.right = node;}
}

c.删除:

分析:

时间复杂度与查找和插入相同。

代码实现:

public void delete(int val) {if(root == null) {return;}TreeNode cur = root;TreeNode parent = null;while(cur != null) {cur = parent;if (cur.val > val) {//进到左边cur = cur.left;} else if (cur.val < val) {//进到右边cur = cur.right;} else {removeNode(parent,cur);}}
}
private void removeNode(TreeNode parent, TreeNode cur) {if(cur.left == null) {if(cur == root) {cur = cur.right;}else if(parent.right == cur) {parent.right = cur.right;}else if(parent.left == cur) {parent.left = cur.right;}}else if(cur.right == null) {if(cur == root) {cur = cur.left;}else if(parent.right == cur) {parent.right = cur.left;}else if(parent.left == cur) {parent.left = cur.left;}}else {TreeNode tmpParent = cur;TreeNode tmp = cur.right;while(tmp.left != null) {tmpParent = tmp;tmp = tmp.left;}cur.val = tmp.val;if(tmpParent.left == tmp) {tmpParent.left = tmp.right;}if(tmpParent.right == tmp) {tmpParent.right = tmp.right;}}
}

(3)和集合类的关系:

TreeSet和TreeMap即java中运用二叉搜索树实现的Set和Map;但实际上是一颗红黑树,红黑树是一颗近似平衡的二叉搜索树(不会出现一些单只树的情况)。

2.哈希表

(1)概念:

通过构造一种存储结构,和某种函数(hashFunc)使元素的存储位置与它的关键码之间能够建立一 一映射的关系,从而在查找时候能很快速的查找到对应的元素。构造出来的存储结构就成为哈希表,某种转换函数称为哈希函数,上述这中查找方式称为哈希(散列)方法。

eg:

(2)冲突:

a.概念:

不同关键字通过哈希函数计算出相同的哈希地址。

b.避免:

冲突是不能够完全避免的,我们只能设计一个比较合理的哈希函数来尽量降低哈希冲突率

直接定制法:Hash(key) = A * key + B 使用场景:适合查找比较小且连续的情况。

除留余数法:Hash(key) = key % p(p <= m,m为哈希表的长度)

c.负载因子调节(\alpha):

\alpha = 填入表中的元素/哈希表的长度,\alpha越大,表明冲突的概率越大,反之则越小。

d.解决方式:

闭散列:

有线性探测和二次探测两种方式:

线性探测:

线性探测有个缺陷就是冲突的元素易容易堆积在一起。 

二次探测:

研究表明:当表的长度为质数并且负载因子不超过0.5时,新的表项一定能插入,而且任何一个位置都不会被探查两次。因此只要表中有一半的位置,就不存在表满的问题。此时在搜索时可以不考虑装满的情况,但在插入时必须确保表的负载因子不超过0.5,否则需要扩容。

因此闭散列最大的缺陷就是表的利用率比较低。

开散列:(哈希桶,开链法,链地址法)

各个桶中的元素通过一个单链表串起来,各链表头节点存储在哈希表中。

eg:

从上图我们可以看出每个哈希桶中放的都是冲突的元素,此时就可以将开散列认为时是把一个大集合中的搜索问题转化为在小集合中做搜索了。

 3.Map和Set

Set和Map都是java中专门用来搜索的容器/数据结构,其搜索的效率与具体的实列类有关。

以前的搜索方式:直接遍历,二分查找......,这些更适合于静态查找。

而Set和Map更适合于动态查找。

搜索的数据:关键字(key)和关键字对应的称为值(value),它们一起称为key-value键值对。一般有两种模型:纯key模型(Set)和纯key-value模型(Map)。

(1)TreeMap,HashMap:

map是一个接口没有继承于Collection接口,存储的是key-value键值对,key是唯一的,不能重复。

a.使用:

 关于Map.Entry<K,V>的说明:

Entry也是一个接口,只不过是Map内部实现的接口,它是用来存放key-value键值对的映射关系。

主要有三个使用方法:

 Map.Entry<K,V>中没有提供设置key的方法。

b.HashMap源码相关解析:

c.比较:

d.注意:

Map是一个接口,不能够进行实列化对象,要new对象只能通过TreeMap或者HashMap来实现。

Map中key,value的类型可以是所有类型,但TreeMap中的key不能为nul,而HashMap可以

Map中key是唯一的,value不是唯一的。

Map中的key是不能直接进行修改的,Map.Entry中只提供了setValue方法,并为提供setKey方法,所以要想进行修改key,只能删除这个键值对,重新放入元素。

(2)TreeSet,HashSet:

Set是一个接口,继承与Collection接口,Set集合类可以达到天然去重的效果。

a.使用:

b.比较:

c.注意:

Set是一个接口,不能直接实例化对象,只能通过TreeSet或HashSet来new对象。

Set中的元素是唯一的,所以有天然去重的效果。

TreeSet中的值不能为null,HashSet可以。

Set的底层就是有Map来实现的,其使用key与Object一个默认对象作为键值对插入到Map中的。

Set中的key也是不能修改的,要修改只能删除,重新放入。

Set常见实列化的类有TreeSet和HashSet,此外还有LinkedHashSet,其是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。

4.OJ题:

(1)随机链表的复制

分析:

代码实现:

class Solution {public Node copyRandomList(Node head) {HashMap<Node,Node> map = new HashMap<>();Node cur = head;while(cur != null) {Node node = new Node(cur.val);map.put(cur,node);cur = cur.next;}cur = head;while(cur != null) {map.get(cur).next = map.get(cur.next);map.get(cur).random = map.get(cur.random);cur = cur.next;}return map.get(head);}
}

 (2)旧键盘

分析:

代码实现:

public static void func(String str1, String str2) {Set<Character> set = new HashSet<>();for (char ch : str2.toUpperCase().toCharArray()) {set.add(ch);}Set<Character> set1 = new HashSet<>();for (char ch : str1.toUpperCase().toCharArray()) {if (!set.contains(ch) && !set1.contains(ch)) {System.out.print(ch);set1.add(ch);}}
}

(3)前k个高频单词

分析:

代码实现:

class Solution {public List<String> topKFrequent(String[] words, int k) {HashMap<String, Integer> map = new HashMap<>();for (String word : words) {if (map.get(word) == null) {map.put(word, 1);} else {int val = map.get(word);map.put(word, val + 1);}}// 建立小根堆PriorityQueue<Map.Entry<String, Integer>> queue = new PriorityQueue<>(new Comparator<Map.Entry<String, Integer>>() {@Overridepublic int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {if (o1.getValue().compareTo(o2.getValue()) == 0) {return o2.getKey().compareTo(o1.getKey());}return o1.getValue().compareTo(o2.getValue());}});for (Map.Entry<String, Integer> entry : map.entrySet()) {if (queue.size() < k) {queue.offer(entry);} else {Map.Entry<String, Integer> tmp = queue.peek();if (tmp.getValue().compareTo(entry.getValue()) < 0) {queue.poll();queue.offer(entry);} else {// 按照字符顺序排if (tmp.getValue().compareTo(entry.getValue()) == 0) {if (tmp.getKey().compareTo(entry.getKey()) > 0) {queue.poll();queue.offer(entry);}}}}}List<String> list = new LinkedList<>();for (int i = 0; i < k; i++) {Map.Entry<String, Integer> tmp = queue.poll();list.add(tmp.getKey());}Collections.reverse(list);return list;}
}

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

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

相关文章

【单机锁】实现原理

文章目录 1.互斥锁 sync.Mutex 的实现原理&#xff1b;1.1获取策略有如下两种&#xff1a;1.2sync.Mutex的方案1.2.1具体方案如下&#xff1a;1.2.2转换的条件&#xff1a;1.2.3运行的两种模式&#xff1a;1.2.4两种模式的转换条件1.2.5唤醒标识&#xff1a; 1.3源码走读 2. sy…

猫头虎分享:PyTorch异常ModuleNotFoundError: No module named ‘torch’解决方案

&#x1f42f; 猫头虎分享&#xff1a;PyTorch异常ModuleNotFoundError: No module named ‘torch’解决方案 &#x1f4bb; 摘要 在本篇博客中&#xff0c;我们将深入探讨如何解决PyTorch中常见的“ModuleNotFoundError: No module named ‘torch’”错误。通过详细的步骤指…

差分法求解 Burgers 方程(附完整MATLAB 及 Python代码)

Burgers 方程的数值解及误差分析 引言 Burgers 方程是一个非线性偏微分方程&#xff0c;在流体力学、非线性声学和交通流理论中有广泛应用。本文将通过数值方法求解带粘性的 Burgers 方程&#xff0c;并分析其误差。 方程模型 Burgers 方程的形式为&#xff1a; u t u u …

Jmeter下载、安装、永久汉化(Windows环境)

1、JDK下载 JDK8下载地址https://www.oracle.com/java/technologies/downloads/#java8-windows JDK8的Windows的64位&#xff1a; 2、Jmeter下载 jmeter下载地址https://jmeter.apache.org/download_jmeter.cgi 3、配置环境变量 安装好后&#xff0c;把jdk和jmeter都配置到…

Docker从入门到实践教程(电子版)

前言 Docker 是个伟大的项目&#xff0c;它彻底释放了虚拟化的威力&#xff0c;极大降低了云计算资源供应的成本&#xff0c;同时让应用的 分发、测试、部署和分发都变得前所未有的高效和轻松&#xff01; 本电子书既适用于具备基础 Linux 知识的 Docker 初学者&#xff0c;也…

隧道可视化:实时监控保障行车安全

通过图扑可视化实现隧道的实时监控、数据分析及智能报警系统&#xff0c;提供全面的隧道管理和决策支持&#xff0c;提升行车安全&#xff0c;优化维护策略&#xff0c;确保交通顺畅。

【b站-湖科大教书匠】6 应用层 - 计算机网络微课堂

课程地址&#xff1a;【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;】 https://www.bilibili.com/video/BV1c4411d7jb/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 6 应用层 6.1 应用层概述 6.2 客户-服务器方式和对等方…

PsExec横向:IPCPTHPTT

一.IPC下的PsExec 二.PTH下的psexec&#xff08;CS操作&#xff09; 三.PTT下的psexec PsExec工具&#xff1a; psexec 是 windows 下非常好的一款远程命令行工具。psexec的使用不需要对方主机开方3389端口&#xff0c;只需要对方开启admin$共享和ipc$ (该共享默认开启&#…

Spring boot 后端向前端发送日期时间发现少了8小时

问题 数据库 后端的控制台输出 前端控制台输出 可以发现少了8小时 问题 springboot 向前端响应数据是默认 Json 格式&#xff0c;所以会有类型转换&#xff0c;springboot 就通过 Jackson 来对 data 类型数据进行转换&#xff0c;但是Jackson 类型的时区是 GMT&#xff0c;与…

Google AI非坦途

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Pytorch框架之神经网络

一、全连接神经网络的整体结构 二、全连接神经网络的单元结构 找出一组w,b使得结果最优 三、常见激活函数 四、前向传播 学习率是指训练模型时每次迭代更新模型参数的步长。 五、梯度下降法 六、反向传播计算 七、总结 1、准备数据 2、搭建模型 3、开始训练(设置学习率、…

【TS】TypeScript中的接口(Interface):对象类型的强大工具

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 TypeScript中的接口(Interface):对象类型的强大工具引言1. 接口的基本概念1.1 什…

【基于PSINS】UKF/SSUKF对比的MATLAB程序

UKF与SSUKF UKF是&#xff1a;无迹卡尔滤波 SSUKF是&#xff1a;简化超球面无迹卡尔曼滤波 UKF 相较于传统的KF算法&#xff0c;UKF能够更好地处理非线性系统&#xff0c;并且具有更高的估计精度。它适用于多种应用场景&#xff0c;如机器人定位导航、目标跟踪、信号处理等。…

【人工智能】深度剖析:Midjourney与Stable Diffusion的全面对比

文章目录 &#x1f34a;1 如何选择合适的AI绘画工具1.1 个人需求选择1.2 比较工具特点1.3 社区和资源 &#x1f34a;2 Midjourney VS Stable Diffusion&#xff1a;深度对比与剖析 2.1 使用费用对比 2.2 使用便捷性与系统兼容性对比 2.3 开源与闭源对比 2.4 图片质量对比 2.5 上…

19145 最长无重复子数组

这个问题可以使用滑动窗口的方法来解决。我们可以使用两个指针&#xff0c;一个指向子数组的开始&#xff0c;一个指向子数组的结束。然后我们使用一个哈希表来记录每个元素最后出现的位置。当我们遇到一个已经在子数组中出现过的元素时&#xff0c;我们就将开始指针移动到这个…

Mac文件拷贝到移动硬盘怎么做Mac拷贝之后Win电脑里看不到

在日常使用mac电脑的过程中&#xff0c;我们经常需要将一些重要的文件备份到外部硬盘上&#xff0c;以防止数据丢失或电脑故障。传输文件到硬盘可以通过多种方法实现&#xff0c;比如拖拽或者复制至移动硬盘&#xff0c;但有时也会遇到移动硬盘无法粘贴&#xff0c;或拷贝后无法…

SSRF (服务端请求伪造)

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

图像生成中图像质量评估指标—PSNR的详细介绍

文章目录 1. 背景介绍2. 实际应用3. 总结和讨论 1. 背景介绍 峰值信噪比&#xff08;Peak Signal-to-Noise Ratio&#xff0c;简称PSNR&#xff09;是一种广泛应用于图像和视频处理领域的客观图像质量评价指标。它主要用于衡量图像的噪声水平和图像质量&#xff0c;可以用来评…

Python酷库之旅-第三方库Pandas(051)

目录 一、用法精讲 186、pandas.Series.is_monotonic_increasing属性 186-1、语法 186-2、参数 186-3、功能 186-4、返回值 186-5、说明 186-6、用法 186-6-1、数据准备 186-6-2、代码示例 186-6-3、结果输出 187、pandas.Series.is_monotonic_decreasing属性 187…

嵌入式人工智能(34-基于树莓派4B的红外传感器、紫外传感器、激光传感器)

这三种光传感器都是不可见光传感器&#xff0c;光是由电场和磁场交替传播而形成的波动现象。光是一种电磁辐射&#xff0c;属于电磁波的一种。下图是电磁波的频谱范围&#xff0c;生活中多数光是看不到的&#xff0c;但是确真实存在&#xff0c;本文介绍几种光传感器&#xff0…