3、哈希表、映射与集合

1 实现与特性

1.1 哈希表(Hash Table 散列表)

  1. 是根据关键码值(Key value)而直接进行访问的数据结构
  2. 通过把关键值映射到表中一个位置来访问记录,加快了查找速度
  3. 这个映射函数叫做哈希(散列函数(Hash Function),存放记录的数组叫做哈希表(或散列表)

1)实际应用

  1. 电话号码簿
  2. 用户信息表
  3. 缓存(LRU Cache)
  4. 键值对存储(Redis)

2)实现原理

key通过哈希函数,哈希函数返回一个下标存入哈希表
在这里插入图片描述

Hash Collisions(哈希碰撞)

指的是:不同的数据,经过哈希函数之后会得到相同的值
解决方法

  1. 增加维度:先从这个位置拉出一个链表来,实现一个位置存入多个数,这叫做拉链式解决冲突法
    在这里插入图片描述

3)时间复杂度分析

lookup:O(1) ,如果一个位置有链表,最坏将达到O(n),但是可以看做平均为O(1)

4)代码实现(Map, Set)

Map 键值对,key不重复 (python中是dict字典)

Set 不重复元素的集合

boolean add​(E e) 如果指定的元素不存在,则将其指定的元素添加(可选操作)。
boolean addAll​(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合
void clear​() 从此集合中删除所有元素(可选操作)。
boolean contains​(Object o) 如果此集合包含指定的元素,则返回 true 。
boolean containsAll​(Collection<?> c) 如果此集合包含指定集合的所有元素,则返回 true 。
boolean isEmpty​() 如果此集合不包含元素,则返回 true 。
Iterator<E> iterator​() 返回此集合中元素的迭代器。
boolean remove​(Object o) 如果存在,则从该集合中删除指定的元素(可选操作)。
boolean removeAll​(Collection<?> c) 从此集合中删除指定集合中包含的所有元素(可选操作)。
int size​() 返回此集合中的元素数(其基数)。

list

2 算法题解

1)[49] 字母异位词分组(hash表解法)

/*
 * @lc app=leetcode.cn id=49 lang=java
 *
 * [49] 字母异位词分组
 * String.valueOf(char []) 将char[]转换为字符串
 * 
 * 方法1.将每个单词中的字母排序
 * get:返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。
 */

// @lc code=start
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 先创建一个哈希表
        HashMap<String, List<String>> hash = new HashMap<>();
        for (int i = 0; i < strs.length; i++) {
            char[] s_arr = strs[i].toCharArray(); // 将单个字符串转换成char数组
            // 排序
            Arrays.sort(s_arr);
            // 映射到 key
            String key = String.valueOf(s_arr); //char[]转换成String字符串存入key
            // 如果key在else中已经创建了就直接添加到对应的类中
            if (hash.containsKey(key)) { // containsKey:如果此映射包含指定键的映射,则返回true 
                hash.get(key).add(strs[i]);
            } else { // 如果没有key,先新建一个数组存放strs[i] 并对应key存放到hash表中
                List<String> temp = new ArrayList<String>();
                temp.add(strs[i]);
                hash.put(key, temp);
            }

        }
        return new ArrayList<List<String>>(hash.values());
    }
}
// @lc code=end

在这里插入图片描述

2)两数之和(hash表解法)

import java.util.HashMap;
import java.util.Map;

import javax.naming.spi.DirStateFactory.Result;

/*
 * @lc app=leetcode.cn id=1 lang=java
 *
 * [1] 两数之和
 * 方法2.hash表解法
 * 1)两遍hash表,
 * 第一次先遍历将数组中每个值标上序号存入hashmap
 * 第二次遍历数组找到与hashmap中满足  nums[i] + map[key] = target
 */

// @lc code=start
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        int[] result = new int[2];
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i], i); // 将数组内元素存入map, 数组元素作为key
        }
        for (int i = 0; i < nums.length; i++) {
            int key = target - nums[i]; // 算出满足target所需要的值后在map中比对
            // 因为不能重复利用数组元素,所以也要比对满足条件的key对应的value是否与数组下标相等
            if (map.containsKey(key) && map.get(key) != i) {
                result[1] = i;
                result[0] = map.get(key);
                // return new int[] {i, map.get(key)};
            }
        }
        return result;
        // throw new IllegalArgumentException("No two sum solution");
    }
}
// @lc code=end

发布了90 篇原创文章 · 获赞 4 · 访问量 1436

猜你喜欢

转载自blog.csdn.net/weixin_44145258/article/details/103564228