在leetCode算法题中,哈希的解法是十分常见的。所以懂得哈希是十分重要的。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i< nums.length; i++) {
if(map.containsKey(target - nums[i])) {
return new int[] {map.get(target-nums[i]),i};
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
}
常见的求哈希值的方法:
1.直接定址法:
取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B。
优点:简单、均匀
缺点:需要事先知道关键字的分布情况
(适合查找比较小且连续的情况)
2.除留余数法:
设散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数,按照哈希函数:Hash( key ) = key % p ( p <= m) ,将关键码转换成哈希地址
【哈希冲突】:
对于两个数据元素的关键字Ki和Kj(i != j),有Ki != Kj ( i != j) ,但HashFun( Ki ) ==HashFun( Kj ) ,将该种现象称为哈希冲突或哈希碰撞。
闭散列法:
在元素插入时遇到哈希冲突,我们可选择线性探查法处理冲突,还可以选择二次探查法处理冲突。
这里我们分析下线性探查法:
给出一组元素,它们的关键码为:37,25,14,36,49,68,57,11,散列表为HT[12],表的大小 m=12 ,假设采用Hash(key)= key % p ;(p=11)11是最接近m的质数,就有:
添加元素时,使用散列函数确定元素的插入位置,如果此空间有值:
1.该值是所要插入元素的关键码,不进行插入。
2.产生冲突,依次查看其后的下一个桶,如果发现空位置插入新元素