Java HashSet和ArrayList的查找Contains()时间复杂度
今天在刷leetCode时,碰到了一个题是这样的。
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
看到这个题的第一时间,就想到了利用集合ArrayList来存储,并且判断。
代码:
class Solution {
public boolean containsDuplicate(int[] nums) {
Set<Integer> list=new HashSet<>();
for (int i=0;i<nums.length;i++){
if(list.contains(nums[i])){
return true;
}else {
list.add(nums[i]);
}
}
return false;
}
}
然而,当数据量足够大的时候,会提示超出时间限制
后来又用了指针遍历数组,时间复杂度勉强通过,也不尽人意
最后又用到了HashSet,时间复杂度已经很好了
public static boolean containsDuplicate(int[] nums) {
Set<Integer> set=new HashSet<>();
for (int i=0;i<nums.length;i++){
if(set.contains(nums[i])){
return true;
}else {
set.add(nums[i]);
}
}
return false;
}
这个时候。引发了我对这两者的思考,
这道题不但在考你的基础算法实现,还涉及到算法效率优化问题。也就是必须要关注算法的时间复杂度。
既然如此,就趁这个机会加深一下ArrayList与HashSet元素查找的时间复杂度区别,实际上就是底层的实现区别。
ArrayList本质就是通过数组实现的,查找一个元素是否包含要用到遍历,时间复杂度是O(n)
而HashSetHashSet的查找是通过HashMap的KeySet来实现的,判断是否包含某个元素的实现,时间复杂度是O(1)
ArrayList判断是否包含某个元素的源码实现:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++) //从头遍历
if (o.equals(elementData[i]))
return i;
}
return -1;
}
HashSet判断是否包含某个元素的源码实现:
public boolean contains(Object o) {
return map.containsKey(o);
}
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) { //直接通过hash确定元素位置,不用从头遍历
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))//部分情况下可能会继续遍历链表定位
return e;
} while ((e = e.next) != null);
}
}
return null;
}
Java HashSet和ArrayList的查找Contains()时间复杂度的更多相关文章
- 【Java必修课】ArrayList与HashSet的contains方法性能比较(JMH性能测试)
1 简介 在日常开发中,ArrayList和HashSet都是Java中很常用的集合类. ArrayList是List接口最常用的实现类: HashSet则是保存唯一元素Set的实现. 本文主要对两者 ...
- Java 集合:HashSet 与 ArrayList
Set 集合是无序不可以重复的的.List 集合是有序可以重复的. Java 集合:HashSet 与 hashCode.equals 博客里面已经说到这个问题,但是解释的还是不够清楚. 看一个小例子 ...
- 浅谈Java语言中ArrayList和HashSet的区别
Java语言中ArrayList和HashSet的区别 2019-04-10 13:22:49 一.基本区别 首先一起看个实例,其代码如下: package com.MrZ_baby.com; i ...
- java集合(ArrayList,Vector,LinkedList,HashSet,TreeSet的功能详解)
说起集合,我们会潜意识里想到另外一个与之相近的名词——数组,OK!两者确实有相似之处,但也正是这点才是我们应该注意的地方,下面简单列出了两者的区别(具体功能的不同学习这篇文章后就会明白了): 数组 长 ...
- Java集合之ArrayList与LinkList
注:示例基于JDK1.8版本 参考资料:Java知音公众号 本文超长,也是搬运的干货,希望小伙伴耐心看完. Collection集合体系 List.Set.Map是集合体系的三个接口. 其中List和 ...
- Java-Runoob-高级教程-实例-数组:14. Java 实例 – 在数组中查找指定元素
ylbtech-Java-Runoob-高级教程-实例-数组:14. Java 实例 – 在数组中查找指定元素 1.返回顶部 1. Java 实例 - 在数组中查找指定元素 Java 实例 以下实例 ...
- Java HashSet和HashMap源码剖析
转自: Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说Ha ...
- Java之——删除ArrayList中的反复元素的2种方法
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47414935 ArrayList是Java中最经常使用的集合类型之中的一个.它同意 ...
- 从源码看Java集合之ArrayList
Java集合之ArrayList - 吃透增删查改 从源码看初始化以及增删查改,学习ArrayList. 先来看下ArrayList定义的几个属性: private static final int ...
随机推荐
- CICS FILE OPEN
CEMT I CECD V FILE() GROUP() CEDA check error log in JESYSMSG FILE OPEN/CLOSE STATUS CICS ACTION res ...
- input | button | textarea 元素的checked, disabled,hidden属性控制
这三种元素涉及到的checked, disabled,hidden属性的控制方法如下 一.attribute方法: //以下3行,都会影响HTML的( checked | disabled | hid ...
- Postman Interceptor和postman更改id仍然无法使用的,从这里下载相同版本的postman和interceptor插件
1.postman安装: chrome://extensions/打开,把下载好的postman插件拖到里面就可以了. 2.Postman interceptor安装: chrome://extens ...
- spring启动异步线程
大纲: spring启动异步线程 spring配置线程池 一.spring启动异步线程 spring启动异步线程方法就是在方法上加上注解@Async,然后启动类或配置类上加上注解@EnableAsyn ...
- 「题解」:$Smooth$
问题 A: Smooth 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...
- 【Flutter学习】基本组件之基本表单组件
一,概述 表单时一个包含表单元素的区域. 表单元素允许用户输入内容,比如文本域,下拉列表,单选框,复选框等.常见的应用场景有:登录,注册,输入信息等. 表单里有两个重要的组件: Form:用来做整个表 ...
- 向量vector 容器浅析
一.什么是vector? 向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container).跟任意其它类型容器一样,它能够存放各种类型的对象.可以简单的认为,向量是一个能 ...
- 简单理解Ext.DomQuery操作CSS3选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- oracle主要的动态视图与基表的对应关系
动态视图 基表 GV$ACCESS x$ksuses,x$kglob,x$kgldp,x$kgllk GV$ACTIVE_INSTANCES x$ksimsi GV$ACTIVE_SESS_POOL_ ...
- HTML中margin和padding的区别
我们以DIV为一个盒子例子,既然和显示生活中的盒子一样,那我们想一下,生活中的盒子 内部是不是空的好用来存放东西,而里面存放东西的区域我们给他起个名字叫“content(内 容)”,而盒子的纸壁给他起 ...