1.题目
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例:
s = “abaccdeff”
返回 “b”
s = “”
返回 " "
限制:
0 <= s 的长度 <= 50000
2.初始思路
1.哈希表
遍历数组,存入哈希表,键为字符,值为出现次数
再次遍历,在哈希表中查找,若出现次数为1,输出此字符
时间复杂度:N(第一次全遍历N,第二次1-N,哈希表1)
空间复杂度:1(所有小写字母的个数为26)
2.辅助数组
构造辅助数组,第一个角标位代表a,其他依次代表bc等等
遍历数组,将字符出现次数存入辅助数组相应角标位的值
再次遍历,在辅助数组中查找,若对应角标元素值为1,则返回
时间复杂度:N(第一次全遍历N,第二次1-N)
空间复杂度:1(辅助数组大小为26)
3.初始算法实现
class Solution {
public char firstUniqChar(String s) {
Map<Character, Integer> map = new HashMap<>();
for(int i = 0; i < s.length(); i++)
{
if(map.containsKey(s.charAt(i)))
map.put(s.charAt(i), 2);
else
map.put(s.charAt(i), 1);
}
for(int i = 0; i < s.length(); i++)
{
if(map.get(s.charAt(i)) == 1)
return s.charAt(i);
}
return ' ';
}
}
class Solution {
public char firstUniqChar(String s) {
int [] dic = new int [26];
for(int i = 0; i < s.length(); i++)
{
dic[s.charAt(i) - 97]++;
}
for(int i = 0; i < s.length(); i++)
{
if(dic[s.charAt(i) - 97] == 1)
return s.charAt(i);
}
return ' ';
}
}
4.交流后总结
1.哈希表
- 与初始思路一致,但有一些细节可以改变:
使用boolean型变量作为值,可以简化判断过程:哈希表中不存在,值为true,存在,值为false
将字符串转化为数组进行操作,遍历时更简便
class Solution {
public char firstUniqChar(String s) {
Map<Character, Boolean> dic = new HashMap<>();
char[] ch = s.toCharArray();
for(char c : ch)
dic.put(c, !dic.containsKey(c));
for(char c : ch)
if(dic.get(c))
return c;
return ' ';
}
}
2.辅助数组
将字符串转化为数组进行操作,遍历时更简便
class Solution {
public char firstUniqChar(String s) {
int [] dic = new int [26];
char[] ch = s.toCharArray();
for(char c : ch)
dic[c - 97]++;
for(char c : ch)
if(dic[c - 97] == 1)
return c;
return ' ';
}
}
3.有序哈希表
有序哈希表中的键值对是按照插入顺序排列的,故可以通过遍历有序哈希表来获得只出现一次的字符
Java中有序哈希表使用LinkedHashMap实现
class Solution {
public char firstUniqChar(String s) {
Map<Character, Boolean> dic = new LinkedHashMap<>();
char[] ch = s.toCharArray();
for(char c : ch)
dic.put(c, !dic.containsKey(c));
for(Map.Entry<Character, Boolean> entry: dic.entrySet())
if(entry.getValue())
return entry.getKey();
return ' ';
}
}
5.相关知识
-
空格的ASCII码值为32;
数字0到9的ASCII码值分别为48到57;
大写字母“A”到“Z”的ASCII码值分别为65到90;
小写字母“a”到“z”的ASCII码值分别为97到到122 -
String类:
toCharArray():将字符串转化为字符数组 -
Map的遍历
最常用的方法是在for-each中使用entries实现
Map<Integer, Integer> map = new HashMap<>();
for(Map.Entry<Integer, Integer> entry: map.entrySet)
{
entry.getKey();
entry.getValue();
}