开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
描述
给定一个字符串
s,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回-1。
- 示例 1:
输入: s = "leetcode"
输出: 0
- 示例 2:
输入: s = "loveleetcode"
输出: 2
- 示例3
输入: s = "aabb"
输出: -1
- 提示:
1 <= s.length <= 105s只包含小写字母
解析
根据题意,本题是一个字符串的数据结构,题目比较简单,解法也有很多种,这里就考虑两种解法。
方法一:
第一次遍历时,使用哈希统计出字符串中每个字符出现的次数。然后在第二次循环时,我们只要遍历到只出现一次的字符,然后直接返回它的索引,如果遍历完成还是没有满足条件的数据,那么遍历结束后返回 -1。
Java解题过程如下:
class Solution {
public int firstUniqChar(String s) {
Map<Character, Integer> frequency = new HashMap<Character, Integer>();
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
frequency.put(ch, frequency.getOrDefault(ch, 0) + 1);
}
for (int i = 0; i < s.length(); ++i) {
if (frequency.get(s.charAt(i)) == 1) {
return i;
}
}
return -1;
}
}
- 时间复杂度:O(n),其中 n是字符串 s的长度。
- 空间复杂度:O(∣Σ∣),其中 \SigmaΣ 是字符集,在本题中 s 只包含小写字母,因此 |Σ∣≤26。我们需要 O(∣Σ∣) 的空间存储哈希映射。
运行结果:
执行结果:通过
执行用时:25 ms, 在所有 Java 提交中击败了41.44%的用户
内存消耗:41.9 MB, 在所有 Java 提交中击败了41.04%的用户
方法二:
方法二是在上面方法一的基础上进行改动,在第二次将遍历对象换成哈希映射。在第一次遍历结束,我们只需要再遍历一次哈希映射中的全部值,找出其中不为 -1 的最小值,如果哈希映射中的所有值均为 -1,就返回 -1。
方法二的时间复杂度和空间复杂度一致。
class Solution {
public int firstUniqChar(String s) {
Map<Character, Integer> position = new HashMap<Character, Integer>();
int n = s.length();
for (int i = 0; i < n; ++i) {
char ch = s.charAt(i);
if (position.containsKey(ch)) {
position.put(ch, -1);
} else {
position.put(ch, i);
}
}
int first = n;
for (Map.Entry<Character, Integer> entry : position.entrySet()) {
int pos = entry.getValue();
if (pos != -1 && pos < first) {
first = pos;
}
}
if (first == n) {
first = -1;
}
return first;
}
}
运行结果:
执行结果:通过
执行用时:20 ms, 在所有 Java 提交中击败了62.33%的用户
内存消耗:42 MB, 在所有 Java 提交中击败了28.91%的用户