题目描述
题干:
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:
s = "leetcode"
返回 0
s = "loveleetcode"
返回 2
题解思路
注意是找到不重复的字符,所以这里首先想到的时哈希表统计每个字符出现的次数,或则是把重复的元素的值置为-1
官方题解改了一个利用队列解决的方法,只需要保留第一个不重复的元素 ,所以和先进先出的队列结构十分吻合
不过因为有的重复元素没有出现在头部,所以不影响返回结果,所以采用了一种延时删除的方法,即等它出现在头部在删除
正确代码
class Solution {
public int firstUniqChar(String s) {
HashMap<Character, Integer> hashMap = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
hashMap.put(ch,hashMap.getOrDefault(ch,0) + 1);
}
for (int i = 0; i < s.length(); i++){
if (hashMap.get(s.charAt(i)) == 1){
return i;
}
}
return -1;
}
}
总结
这里注意到一个问题,在平时哈希表的题目中,在定义哈希表的时候会出现Map和HashMap两种定义方式
HashMap<Character,Integer> hashMap = new HashMap<>();
Map<Character,Integer> map = new HashMap<>();
这里说明一下两者的区别
Map是一个接口,HashMap继承AbstractMap接口和实现了Map接口的类
Map是存储键和值这样的双列数据集合,但存储的数据是没有顺序的,其键不能重复,但其值是可以重复的,可以通过每一个键找到每一个对应的值
HashMap线程不同步的,即线程不安全的,但只有一个线程访问时效率较高
所以两者可以在线程安全的前提下同样使用,平时还是使用HashMap比较多一些,既然说到这里就列一下HashMap的常用方法吧
常用的增删改查方法
put(key,value) 添加一个键值对,返回添加的值,若key已存在,则value覆盖以前的值
remove(key) 删除指定key对应的键值对,返回删除的value值
replace(key,value) 将指定的key对应的value值替换为给定的value值,返回替换掉的值
get(key) 获取key对应的value值
HashMap的每一对键值对都是一个Entry的实例对象
Set<key> keySet() 返回集合中所有key的Set集合
Set<Entry<key,value> entrySet() 返回集合中所有键值对的entry实例对象的集合