描述
在一个长为 字符串中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
数据范围:0≤�≤100000≤n≤10000,且字符串只有字母组成。
要求:空间复杂度 �(�)O(n),时间复杂度 �(�)O(n)
题源:第一个只出现一次的字符_牛客题霸_牛客网 (nowcoder.com)
示例1
输入:
"google"
返回值:
4
示例2
输入:
"aa"
返回值:
-1
方法一:哈希表统计频率(推荐使用)
知识点:哈希表
哈希表是一种根据关键码(key)直接访问值(value)的一种数据结构。而这种直接访问意味着只要知道key就能在�(1)O(1)时间内得到value,因此哈希表常用来统计频率、快速检验某个元素是否出现过等。
思路:
既然要找第一个只出现一次的字符,那只要我们统计每个字符在字符串中出现的次数,后续不就可以找到第一个只出现一次的字符了吗?
统计频率可以建立一个哈希表,遍历字符串的同时,统计每个字符出现的频率,然后再从头遍历一次字符串,在哈希表中查看每个字符串的频率,找到第一个只出现一次的字符串,返回位置,如果没找到返回-1即可。
具体做法:
- step 1://利用map的key记录目标字符串,用value记录该字符串的下标, //如果重复出现两次就把value改为-1
- step 2:再次遍历字符串,对于每个字符,检查哈希表中出现次数是否为1,找到第一个即可。
- step 3:遍历结束都没找到,那就是没有,返回-1,因为map不是俺顺序储存的,所以下标小的才是所求的;
具体做法:
public static int FirstNotRepeatingChar(String str) {
int ans = str.length();
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < str.length(); i++) {
//利用map的key记录目标字符串,用value记录该字符串的下标
String temp = str.substring(i, i + 1);
if (!map.containsKey(temp)) {
map.put(temp, i);
} else {
//如果重复出现两次就把value改为-1
map.put(temp, -1);
}
}
for (String temp : map.keySet()) {
//因为map不是俺顺序储存的,所以下标小的才是所求的;
if (map.get(temp) != -1) {
ans = Math.min(ans,map.get(temp));
}
}
return ans == str.length() ? -1 : ans;
}