题目
标题和出处
标题:字符串中的第一个唯一字符
难度
3 级
题目描述
要求
给定一个字符串 s \texttt{s} s,找到它的第一个不重复的字符,并返回它的下标。如果不存在,则返回 -1 \texttt{-1} -1。
示例
示例 1:
输入:
s
=
"leetcode"
\texttt{s = "leetcode"}
s = "leetcode"
输出:
0
\texttt{0}
0
示例 2:
输入:
s
=
"loveleetcode"
\texttt{s = "loveleetcode"}
s = "loveleetcode"
输出:
2
\texttt{2}
2
示例 3:
输入:
s
=
"aabb"
\texttt{s = "aabb"}
s = "aabb"
输出:
-1
\texttt{-1}
-1
数据范围
- 1 ≤ s.length ≤ 10 5 \texttt{1} \le \texttt{s.length} \le \texttt{10}^\texttt{5} 1≤s.length≤105
- s \texttt{s} s 只包含小写英语字母
解法
思路和算法
这道题要求返回字符串 s s s 中只出现一次的下标最小的字符,因此需要使用哈希表记录字符串 s s s 中每个字符出现的次数。遍历字符串 s s s 一次,对于每个字符,更新该字符在哈希表中记录的出现次数。遍历结束之后,即可知道字符串 s s s 中每个字符的出现次数。
再次遍历字符串 s s s,对于每个字符,从哈希表中获得该字符的出现次数,对于遇到的第一个出现次数是 1 1 1 的字符,返回该字符所在的下标。如果每个字符的出现次数都大于 1 1 1,返回 − 1 -1 −1。
实现方面,由于字符串 s s s 只包含小写英语字母,因此可以使用长度为 26 26 26 的数组代替哈希表记录每个字符的出现次数。
代码
class Solution {
public int firstUniqChar(String s) {
int[] counts = new int[26];
int length = s.length();
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
counts[c - 'a']++;
}
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
if (counts[c - 'a'] == 1) {
return i;
}
}
return -1;
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 s s s 的长度。需要遍历字符串两次。
-
空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣),其中 Σ \Sigma Σ 是字符集,这道题中字符集为全部小写英语字母, ∣ Σ ∣ = 26 |\Sigma| = 26 ∣Σ∣=26。需要使用哈希表或数组记录每个字符的出现次数,空间为 O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣)。