持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
字符串中的第一个为唯一字符
给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。
示例 1:
输入: s = "leetcode"
输出: 0
示例 2:
输入: s = "loveleetcode"
输出: 2
示例 3:
输入: s = "aabb"
输出: -1
提示:
1 <= s.length <= 105s只包含小写字母
解题思路:哈希表存储元素个数
本题可以使用哈希表来实现,用哈希表遍历字符串,把每个元素出现的次数都统计下来,再遍历哈希表,找出那个只出现一次的元素,具体思路是
- 我们用
map实现,map的key存元素的数值,map的value用来存元素在字符串出现的次数 - 遍历完字符串后,在哈希表里找
value里为1的第一个元素,这个元素的索引就是我们要寻找的元素
具体代码:(JAVA)
Map<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;
复杂度分析
- 时间复杂度:O(N^2),
N为字符串长度 - 空间复杂度:O(n),
n为字符集,因为字符串内只有小写字母,所以n <= 26
提交结果
解题思路:哈希表存储元素索引
我们可以对上面的方法优化,使用哈希表存储的为元素索引 具体思路是:
- 对于哈希中的每一个键值对,key表示一个字符,value表示它的首次出现的索引(如果该字符只出现一次)或者
-1(如果该字符出现多次) - 当我们第一次遍历字符串时,设当前遍历到的字符为 c,如果
c是第一次出现,我们就将c与它的索引作为一个键值对加入哈希中,否则我们将c在哈希表中对应的value修改为为-1。 - 在遍历结束后,我们只需要再遍历一次哈希中的所有值,找出第一个不为
-1的键值对,即为第一个不重复字符的索引。如果哈希映射中的所有值均为-1,说明没有唯一字符,我们就返回-1
具体代码:(JAVA)
public int firstUniqChar(String s) {
Map<Character, Integer> hashmap = new HashMap<>();
int n = s.length();
for (int i = 0; i < n; ++i) {
char ch = s.charAt(i);
if (hashmap.containsKey(ch)) {
hashmap.put(ch, -1);
} else {
hashmap.put(ch, i);
}
}
int first = n;
for (Map.Entry<Character, Integer> entry : hashmap.entrySet()) {
int pos = entry.getValue();
if (pos != -1 && pos < first) {
first = pos;
}
}
if (first == n) {
first = -1;
}
return first;
}
复杂度分析
- 时间复杂度:O(N)
- 空间复杂度:O(n),
n为字符集,因为字符串内只有小写字母,所以n <= 26