描述
题目描述
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)
示例
输入:"google" 返回值:4
知识点:字符串,哈希表,数组
难度:一星
题解
解题思路
第一个一般都会想到采用哈希表来保存字符出现的次数、是否只出现一次。
还可以利用其他数据类型的特性,如队列的先进先出,数组的有序性。
方法一:hash存放布尔值
图解

算法流程:
- 哈希表存储布尔值,表示是否只出现一次
- 使用一个Map,只需存储52个大小写字母
- 重复出现的字符,对应value为false,只出现一次的字符value为true
- 遍历字符串数组,找到第一个value为true的字符
Java 版本代码如下:
import java.util.HashMap;
import java.util.Map;
public class Solution {
public int FirstNotRepeatingChar(String s) {
// 只需存储52个大小写字母
Map<Character, Boolean> dic = new HashMap<>(52);
char[] sc = s.toCharArray();
// 重复出现的字符,对应value为false,只出现一次的字符value为true
for(char c : sc)
dic.put(c, !dic.containsKey(c));
// 找到第一个value为true的字符
int cnt = 0;
for(char c : sc){
if(dic.get(c)){
return cnt;
}
++cnt;
}
return -1;
}
}
复杂度分析:
时间复杂度:O(N) ,需遍历 s 两次字符串长度N
空间复杂度:O(1),Map只需要52的空间大小,因此只要常数级空间复杂度
方法二:hash存放字符出现次数
算法流程:
- new 一个 map:key字符, value为出现次数
- 第一次出现的字符存储value为 1
- 统计每个字符串出现次数
- 遍历字符数字,找到第一个字符出现次数为1的字符并返回索引
Java 版本代码如下:
哈希表存储字符出现次数
import java.util.HashMap;
import java.util.Map;
public class Solution {
public int FirstNotRepeatingChar(String str) {
// key字符, value为出现次数
Map<Character, Boolean> map = new HashMap<>(52);
for(int i = 0; i < str.length(); i++) {
// 第一次出现的字符存储value为 1
map.put(str.charAt(i), map.getOrDefault(str.charAt(i), 0) + 1);
}
for(int i = 0; i < str.length(); i++) {
if(map.get(str.charAt(i)) == 1) {
// 直接返回索引
return i;
}
}
return -1;
}
}Python 版本代码如下:
# -*- coding:utf-8 -*-
class Solution:
def FirstNotRepeatingChar(self, s):
# write code here
if not s:
return -1
# 遍历,找到出现次数为1的字符
for i in range(len(s)):
if s.count(s[i]) == 1:
return i
return -1复杂度分析:
时间复杂度:O(N) ,需遍历 s 两次字符串长度N
空间复杂度:O(1),Map只需要52的空间大小,因此只要常数级空间复杂度
总结:学会Map的存储类型的灵活使用
方法三:数组
说到底数组的用法和上面的 Map 差不多,也是存储字母出现次数,只不过需要以字母的ASCII码为下标存储,节省了类似Map存储字符的空间
算法流程:
- new一个数组,数组以每个字母的ASCII码为下标, 存放对应字符出现次数
- 统计每个字符出现次数
- 找到数组中为 1 的对应下标
Java 版本代码如下:
public class Solution {
public int FirstNotRepeatingChar(String str) {
// 数组存储字符出现次数
int[] words = new int[58];
// 统计每个字符出现次数
for(int i = 0;i < str.length();i++){
// 数组以每个字母的ASCII码为下标, 存放对应字符出现次数
words[((int)str.charAt(i))-65] += 1;
}
for(int i = 0; i < str.length(); i++){
if(words[((int)str.charAt(i))-65]==1)
return i;
}
return -1;
}
}Python 版本代码如下:
# -*- coding:utf-8 -*-
class Solution:
def FirstNotRepeatingChar(self, s):
# 数组统计出现次数
single_list = []
for i in range(len(s)):
if s.count(s[i]) == 1:
return i
# 字符存放到数组,用于计数
single_list.append(s[i])
break
if len(single_list) == 0:
return -1
# write code here复杂度分析:
时间复杂度:O(N) ,需遍历 s 两次字符串长度N
空间复杂度:O(1),数组只需要常数级的空间大小,因此只要常数级空间复杂度

京公网安备 11010502036488号