1 实现与特性
1.1 哈希表(Hash Table 散列表)
- 是根据关键码值(Key value)而直接进行访问的数据结构
- 通过把关键值映射到表中一个位置来访问记录,加快了查找速度
- 这个映射函数叫做哈希(散列函数(Hash Function),存放记录的数组叫做哈希表(或散列表)
1)实际应用
- 电话号码簿
- 用户信息表
- 缓存(LRU Cache)
- 键值对存储(Redis)
2)实现原理
key通过哈希函数,哈希函数返回一个下标存入哈希表
Hash Collisions(哈希碰撞)
指的是:不同的数据,经过哈希函数之后会得到相同的值
解决方法
- 增加维度:先从这个位置拉出一个链表来,实现一个位置存入多个数,这叫做拉链式解决冲突法
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