剑指–第一个只出现一次的字符
1,题目:
2,思路:
方法一:有序哈希表:
- 1,在哈希表的基础上,有序哈希表中的键值对是 按照插入顺序排序 的。基于此,可通过遍历有序哈希表,实现搜索首个 “数量为 11 的字符”。
- 2,哈希表是 去重 的,即哈希表中键值对数量 <字符串 s 的长度。当字符串很长(重复字符很多)时,这个方法则效率更高。
方法二:用哈希表(这里用的数组代替了哈希表,其实是用了哈希表的知识):
- 1,要求只出现一次的第一个字符,就需要去计数每一个字符出现了几次。一般都是用哈希表,但是字符往多了数按照扩展的ASCII码也就256个,就可以使用int[]
count来代替哈希表:键就是字符对应的数,值就是该字符出现的次数。 - 2,第一次遍历计数每个字符出现的次数for(char c : chars)
count[c]++;。第二次遍历按顺序去查看该字符出现了几次,如果该字符出现了1次,它就是第一个仅出现一次的字符,直接返回。 - 3,如果第二次遍历没有返回,就说明没有仅出现一次的字符,返回’ '。
- 4,时间复杂度为O(n),空间复杂度为O(n)(因为使用了辅助的字符数组)。
方法三:用map代替哈希表:
与方法一性质是一样的,都是用到了哈希表的实质。只不过这个是用map数组代替了哈希表,但是还是用的哈希表的实质。
3,代码:
方法一:有序哈希表:
class Solution {
public char firstUniqChar(String s) {
/*方法一:有序哈希表:
1,在哈希表的基础上,有序哈希表中的键值对是 按照插入顺序排序 的。基于此,可通过遍历有序哈希表,实现搜索首个 “数量为 11 的字符”。
哈希表是 去重 的,即哈希表中键值对数量 <字符串 s 的长度。当字符串很长(重复字符很多)时,这个方法则效率更高。
*/
Map<Character, Boolean> dic = new LinkedHashMap<>();
char[] sc = s.toCharArray();
for(char c : sc)
dic.put(c, !dic.containsKey(c));
for(Map.Entry<Character, Boolean> d : dic.entrySet()){
if(d.getValue()) return d.getKey();
}
return ' ';
}
}
方法二:用哈希表(这里用的数组代替了哈希表,其实是用了哈希表的知识):
class Solution {
public char firstUniqChar(String s) {
/*
1,要求只出现一次的第一个字符,就需要去计数每一个字符出现了几次。一般都是用哈希表,但是字符往多了数按照扩展的ASCII码也就256个,就可以使用int[] count来代替哈希表:键就是字符对应的数,值就是该字符出现的次数。
2,第一次遍历计数每个字符出现的次数for(char c : chars) count[c]++;。第二次遍历按顺序去查看该字符出现了几次,如果该字符出现了1次,它就是第一个仅出现一次的字符,直接返回。
3,如果第二次遍历没有返回,就说明没有仅出现一次的字符,返回' '。
4,时间复杂度为O(n),空间复杂度为O(n)(因为使用了辅助的字符数组)。
*/
int[] count = new int[256];//统计每个字符出现的次数
char[] chars = s.toCharArray();
for(char c : chars)
count[c]++;
for(char c : chars){
if(count[c] == 1)//判断谁的次数是1谁就是最后结果
return c;
}
return ' ';
}
}
方法三:用map代替哈希表:
class Solution {
public char firstUniqChar(String s) {
/*方法二:用map代替哈希表:
*/
int[] map = new int[256];
Arrays.fill(map, 0);
//map是一个数组变量,0是一个map中元素数据类型的值,作用:填充map数组中的每个元素都是0
//这里的意思就是对map这个数组进行初始化
for(char c: s.toCharArray())
map[c]++;//统计每个字符出现的次数
for(char c: s.toCharArray())
if(map[c] == 1) return c;
return ' ';
}
}