s = "abaccdeff"
返回 "b"
s = ""
返回 " "
class Solution {
public char firstUniqChar(String s) {
// 哈希表
// key: 字符
// value: true代表字符数量为1,false代表字符数量大于1
HashMap<Character, Boolean> hashmap = new HashMap<>();
// 把字符串转换为字符数组
char[] ch = s.toCharArray();
// 遍历所有字符
for (char c : ch) {
// 如果哈希表中不包含当前字符的话,则当前字符目前只有一个,哈希值为 true 。
// 如果哈希表中包含当前字符的话,则当前字符目前大于一个,哈希值为 false 。
hashmap.put(c, !hashmap.containsKey(c));
}
// 再遍历一遍字符,找到了哈希值为 true (即字符只有一个) 的字符直接返回即可
for (char c : ch) {
if (hashmap.get(c))
return c;
}
// 不存在的话就返回单空格
return ' ';
}
}
class Solution {
fun firstUniqChar(s: String): Char {
// 哈希表
// key: 字符
// value: true代表字符数量为1,false代表字符数量大于1
val hashmap = HashMap<Char, Boolean>()
// 把字符串转换为字符数组
val ch = s.toCharArray()
// 遍历所有字符
for (c in ch) {
// 如果哈希表中不包含当前字符的话,则当前字符目前只有一个,哈希值为 true 。
// 如果哈希表中包含当前字符的话,则当前字符目前大于一个,哈希值为 false 。
hashmap[c] = !hashmap.containsKey(c)
}
// 再遍历一遍字符,找到了哈希值为 true (即字符只有一个) 的字符直接返回即可
for (c in ch) {
if (hashmap[c] == true)
return c
}
// 不存在的话就返回单空格
return ' '
}
}
有序哈希表中的键值对是按照插入顺序排序的。由于哈希表是去重的,法 1 中的第二个遍历是遍历所有字符,法 2 中的第二个遍历是遍历哈希表,所以当字符串非常非常非常长的时候,法 2 会比法 1 减少第二个遍历中的循环次数,效率更高。
// 有序哈希表
class Solution {
public char firstUniqChar(String s) {
// 有序哈希表
Map<Character, Boolean> map = new LinkedHashMap<>();
// 将字符串转换为字符数组
char[] ch = s.toCharArray();
// 遍历所有字符
for (char c : ch) {
// 如果哈希表中不包含当前字符的话,则当前字符目前只有一个,哈希值为 true 。
// 如果哈希表中包含当前字符的话,则当前字符目前大于一个,哈希值为 false 。
map.put(c, !map.containsKey(c));
}
// 遍历有序哈希表,找到第一个哈希值为 true (即字符只有一个)的字符直接返回即可
for (Map.Entry<Character, Boolean> entry : map.entrySet()) {
if (entry.getValue())
return entry.getKey();
}
// 不存在的话就返回单空格
return ' ';
}
}
class Solution {
fun firstUniqChar(s: String): Char {
// 有序哈希表
val map = LinkedHashMap<Char, Boolean>()
// 将字符串转换为字符数组
val ch = s.toCharArray()
// 遍历所有字符
for (c in ch) {
// 如果哈希表中不包含当前字符的话,则当前字符目前只有一个,哈希值为 true 。
// 如果哈希表中包含当前字符的话,则当前字符目前大于一个,哈希值为 false 。
map[c] = !map.containsKey(c)
}
// 遍历有序哈希表,找到第一个哈希值为 true (即字符只有一个)的字符直接返回即可
for ((key, value) in map) {
if (value)
return key
}
// 不存在的话就返回单空格
return ' '
}
}