一、问题描述
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:
s = "leetcode" 返回 0
s = "loveleetcode" 返回 2
提示:你可以假定该字符串只包含小写字母。
二、题解
1.实现思路
借助LinkedHashMap的特点:LinkedHashMap继承于HashMap,HashMap是无序的,LinkedHashMap输出时其元素是有顺序的。当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了。
(1)首先判断该字符串是否为空或单个字符,若是,则返回-1或0.即s.length()-1;
(2)将该字符串转化为字符数组;
(1)遍历该字符数组,将每个字符出现的次数保存在LinkedHashMap中;
(2)遍历该map集合,如果对应的值为1,说明该字符串即为第一个唯一的字符,直接break;
(3)遍历字符数组,返回对应的唯一的字符出现的位置,如果不存在,则返回-1。
2.实现代码
class Solution {
public int firstUniqChar(String s) {
// 如何该字符串为空或者是单个字符时
if (s.length()<1){
return s.length()-1;
}
// 将字符串转化为字符数组
char[] chars = s.toCharArray();
// 使用LinkedHashMap保存字符串中的字符和对应的出现的次数
Map<Character,Integer> map = new LinkedHashMap<>();
// 遍历字符数组,添加到Map集合中
for (int i = 0; i < chars.length; i++) {
int count = 0;
if (!map.containsKey(chars[i])){
map.put(chars[i],1);
}else {
map.put(chars[i],map.get(chars[i])+1);
}
}
// 遍历map集合,如果对应的值为1,说明该字符串即为第一个唯一的字符
char c = ' ';
for (Map.Entry<Character,Integer> entry: map.entrySet()) {
if (entry.getValue().equals(1)){
c = entry.getKey();
break;
}
}
// 遍历字符数组,返回对应的唯一字符的位置,如果不存在则返回-1.
for (int i = 0; i < chars.length; i++) {
if (chars[i]==c){
return i;
}
}
return -1;
}
}
我这种方法有点麻烦,后来看了官方题解,发现可以直接用HashMap集合去实现。大家可以看下官方的思路:
官方的代码:
class Solution {
public int firstUniqChar(String s) {
HashMap<Character, Integer> count = new HashMap<Character, Integer>();
int n = s.length();
// build hash map : character and how often it appears
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
count.put(c, count.getOrDefault(c, 0) + 1);
}
// find the index
for (int i = 0; i < n; i++) {
if (count.get(s.charAt(i)) == 1)
return i;
}
return -1;
}
}
在这里说明一下,HashMap的getOrDefault()方法:
getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。