Leetcode力扣-1.两数之和-Java-HashMap的创建、插入、查找等操作

1. 题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

2. 解题方法-Java

刚开始做一整个大无语,第一道题就不会,经过学习后得到了利用HashMap实现时间复杂度为O(n)的结果。

下面是代码和代码的解析:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 创建HashMap,其中Key值代表数组中的值,Value值代表数组中的下标
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            // x为当前数组值所需相加满足target的值
            int x = target - nums[i];
            // 判断map中是否有x值
            if(map.containsKey(x)){
                // 如果有满足target的两个值,则返回两个值的下标
                return new int[]{i, map.get(x)};
            }
            // 如果不满足,则插入当前数组值-当前数组值下标
            map.put(nums[i], i);
        }
        return new int[]{-1, -1};
    }
}

最终提交结果为:

        

         

3. HashMap

HashMap是基于哈希表的Map实现。键是哈希表结构,可以保证键的唯一性。因此,在了解HashMap之前,我们首先要知道哈希表(Hash table),也叫散列表的概念。

3.1 哈希表(Hash table)

以引出哈希表,我们先通过与不同数据结构的插入、删除和查找性能比较,来了解哈希表的性能。

数组:采用一段连续的存储单元来存储数据。对于指定下标的查找,时间复杂度为O(1);通过给定值进行查找,需要遍历数组,逐一比对给定关键字和数组元素,时间复杂度为O(n),当然,对于有序数组,则可采用二分查找,插值查找,斐波那契查找等方式,可将查找复杂度提高为O(logn);对于一般的插入删除操作,涉及到数组元素的移动,其平均复杂度也为O(n)

线性链表:对于链表的新增,删除等操作(在找到指定操作位置后),仅需处理结点间的引用即可,时间复杂度为O(1),而查找操作需要遍历链表逐一进行比对,复杂度为O(n)

二叉树:对一棵相对平衡的有序二叉树,对其进行插入,查找,删除等操作,平均复杂度均为O(logn)。

哈希表:相比上述几种数据结构,在哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下(后面会探讨下哈希冲突的情况),仅需一次定位即可完成,时间复杂度为O(1)!!!

哈希表就利用了数组通过下标可以进行一次查找的特性,因此,哈希表的主干是数组。

于是,就利用存储位置 = f(关键字)的过程,将当前元素关键字通过某函数映射到数组某位置,就可以就可以通过数组下标一次定位,完成相关操作。

哈希冲突(碰撞):

我们插入某个元素时,发现对该元素通过哈希运算得到的存储地址已经被其它元素占用,就称发生了哈希冲突(碰撞)

哈希冲突的解决方案有多种:开放定址法(发生冲突,继续寻找下一块未被占用的存储地址),再散列函数法,链地址法,而HashMap即是采用了链地址法,也就是数组+链表的方式。

3.2 HashMap的操作

HashMap的设计初衷主要是为了解决键值(key-value)对应的关联的,HashMap的优势是可以很快的根据键(key)找到该键对应的值(value),HashMap是一种无序的存储结构。

创建:

HashMap<Integer,Integer> map = new HashMap<>();

 <,>前后分别是键(key)类型和该键对应的值(value)类型。

HashMap是基于数组创建的,HashMap最核心的结构是 transient Entry<K,V> [ ] table ,这个是真正存储HashMap数据的结构。

在new HashMap的时候,会调用HashMap的无参构造函数,而无参构造函数会调用另外一个具有两个参数的构造函数 public HashMap(int initialCapacity, float loadFactor),前一个参数是HashMap的初始化大小,即在创建HashMap的时候,会自动创建一个大小长度为initialCapacity的数组table。如果没有指定数组table的初始化大小,则数组table的初始化大小默认为16。参数loadFactor,它是装载因子,和initialCapacity一样,可以在构造函数中指定大小,如果没有指定的话,则默认值为0.75,意思就是,如果当前数组中实际存储的元素个数与数组长度的比值达到0.75时,数组长度会翻一倍。

插入:

map.put(nums[i], i);

1. 可以在HashMap中插入key为null的键/值对。
2. 在HashMap中插入数据时,如果存在相同key,则用新的value替换旧的value。

判断是否包含指定键Key的值:

map.containsKey(x);

map中的containKey(key)方法是判断该key在map中是否有key存在。如果存在则返回true,反之,返回false。

获取指定键Key的Value的值:

map.get(x);

1. 首先判断输入的key是否为空,如果为空,从hashmap数组下标为0的位置获取值返回
2. 如果不为空,根据key的值,从hashmap数组中获取对应的entry对象,判断这个对象是否为空,为空返回null,不为空返回对应的value值, 获取value的方法中key为空和不为空时的方法里都先判断数组中的元素是否为0 ,如果不为0,才继续查找。

有参考其他博主的文章,并非完全原创嘻嘻。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值