目录
一、哈希表的引出
1、例题
第一种思路,使用Map集合:
先将字符串转换为字符数组,在Map<Character,Integer>集合中保存字符以及字符出现的次数,遍历Map集合取出次数为1所对应的key值,再次遍历字符串,找到对应的索引就解决了
public int firstUniqChar(String s) {
char[] data=s.toCharArray();
Map<Character,Integer> map=new HashMap<>();
for (char i:data){
map.put(i,map.getOrDefault(i,0)+1);
}
for (int i = 0; i < data.length; i++) {
if (map.get(data[i]) == 1) {
return i;
}
}
return -1;
}
将每个字符出现的次数保存到整型数组中,最后找到次数为1的字符即可
public int firstUniqChar(String s) {
//由于s中只包含小写字母,因此就将每个字符出现的频次保存到整型数组中
int[] arr=new int[26];
//遍历字符串,将字符出现的频次保存到arr数组中
for (int i = 0; i <s.length() ; i++) {
char c=s.charAt(i);
//按照-‘a’的规则将每一个小写字母转换为26个数字中的一个
//'c'-'a'=2 'a'-'a'=0
arr[c-'a']++;
}
//遍历字符串,在arr数组中找到出现次数唯一的字符
int retindex=-1;
for (int i = 0; i < s.length(); i++) {
char c=s.charAt(i);
if (arr[c-'a']==1){
retindex=i;
break;
}
}
return retindex;
}
2、哈希表以及哈希函数
上述例题中的第二种方法的arr数组就是一个哈希表,每一个不重复的字符都和一个整型数字一一对应,按照规则(字符-‘a’)将每个字符转换为数字,这个转换操作就叫做哈希函数。
哈希表中需要一种方法将任意数据类型转换为数组的索引,这样的一种方法就称为哈希函数
哈希表就是基于数组的扩展,在数组中如果知道索引,就可以在O(1)的时间复杂度内找到该元素,哈希表体现了空间去换取时间的策略方法
例题:
在数组[9,5,2,7,3,6,8]中查找元素是否存在?
就建立一个长度为10的arr数组,遍历原数组,若元素存在就在arr数组对应的位置添加true
int[] arr=new int[10];
arr[9]=true;
arr[5]=true;
.........直到扫描完整个集合
此时要查询7是否存在,就判断arr[7]的值是否为true
在上述例题中,我们开辟了原数组最大值+1的新的哈希数组,但是当原数组的数字之间的跨度非常大时,或者包含负数,这种方法就不适用了,比如[9,100000,-34,30000000,44]这个数组来说,就没法创造一个数字一一对应的索引的哈希数组了。