NC31 第一个只出现一次的字符
描述
在一个长为 字符串中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
示例1
输入:
"google"
返回值:
4
代码解析:
哈希表统计频率
- step 1:遍历一次字符串,对于每个字符,放入哈希表中统计出现次数。
- step 2:再次遍历字符串,对于每个字符,检查哈希表中出现次数是否为1,找到第一个即可。
- step 3:遍历结束都没找到,那就是没有,返回-1.
import java.util.*;
public class Solution {
public int FirstNotRepeatingChar(String str) {
HashMap<Character, Integer> mp = new HashMap<>();
//统计每个字符出现的次数
for(int i = 0; i < str.length(); i++)
mp.put(str.charAt(i), mp.getOrDefault(str.charAt(i), 0) + 1);
//找到第一个只出现一次的字母
for(int i = 0; i < str.length(); i++)
if(mp.get(str.charAt(i)) == 1)
return i;
//没有找到
return -1;
}
}
队列+哈希表统计位置(扩展思路)
- step 1:利用哈希表记录字符串中出现过的字符的位置,利用两个队列分别记录字符与下标位置(C++可以用pair)。
- step 2:遍历字符串,如果是没有遇到过的字符,就加入哈希表记录位置,同时字符与下标分别入队。
- step 3:遇到出现过的字符,就将其哈希表中的下标置为-1,然后弹出队列首部所有重复的字符,即位置为-1的字符。
- step 4:最后队列中剩余的队首就是第一个只出现一次的字符,因为其他的重复字符都被弹出了,队列为空就代表没有不重复的字符
import java.util.*;
public class Solution {
public int FirstNotRepeatingChar(String str) {
//统计字符出现的位置
HashMap<Character, Integer> mp = new HashMap<>();
Queue<Character> q1 = new LinkedList<>();
Queue<Integer> q2 = new LinkedList<>();
for(int i = 0; i < str.length(); i++){
//没有出现过的字符
if(!mp.containsKey(str.charAt(i))){
mp.put(str.charAt(i), i);
q1.offer(str.charAt(i));
q2.offer(i);
//找到重复的字符
}else{
//位置置为-1
mp.put(str.charAt(i), -1);
//弹出前面所有的重复过的字符
while(!q1.isEmpty() && mp.get(q1.peek()) == -1){
q1.poll();
q2.poll();
}
}
}
return q2.isEmpty() ? -1 : q2.poll();
}
}
class Solution:
def FirstNotRepeatingChar(self , str: str) -> int:
mp = dict()
#统计每个字符出现的次数
for i in str:
if i in mp:
mp[i] += 1
else:
mp[i] = 1
#找到第一个只出现一次的字母
for i in range(len(str)):
if mp[str[i]] == 1:
return i
#没有找到
return -1