持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情
题目
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
解题思路
关键词:第一个出现、只出现一次、字符只包含小写字母
关键信息:只出现一次必须遍历全量、可能存在都只出现一次字符
哈希表遍历解法
哈希表遍历采用键值对方式存储每个字符,其解题思路如下:
- 遍历所有字符并将字符存入哈希表中。
- value为Boolean值依据字符是否已经存在区分,true表示字符值出现一次,false表示不只出现一次。
- 再次遍历字符串在哈希表中找到第一个只出现一次的字符。
public char firstUniqChar(String s) {
char[] chars = s.toCharArray();
HashMap<Character,Boolean> maps = new HashMap();
for(char value : chars){
maps.put(value,maps.get(value) == null);
}
for(char value : chars){
if(maps.get(value)) return value;
}
return ' ';
}
HashMap 和LinkedHashMap的区别
上述解法为什么需要再次遍历字符串查询字符,原因在于HashMap存储是无序的,若直接遍历HashMap可能结果并不是第一个只出现一次的字符。而LinkedHashMap是基于HashMap和双向链表实现,因此可以采用LinkedHashMap来实现上述解法并通过Iterator有序遍历找到期望字符。
index查询解法
利用API方法indexOf求解。遍历字符串中每个字符然后通过indexOf方法查询该字符。当该字符满足以下两个条件说明只在字符串中出现一次:
- indexOf判断当前遍历下标是当前字符第一次出现的位置。
- indexOf判断当前字符在后面索引中不再出现。
API方法除了indexOf(String str)之外还有indexOf(String str, intstartIndex)。后面的intstartIndex表示从指定的索引处开始,返回第一次出现的指定子字符串在此字符串中的索引。
public char firstUniqChar(String s) {
for (int i = 0; i < s.length(); i++) {
char value = s.charAt(i);
//首次出现的位置是当前位置,且后面没有再出现这个字符
if(s.indexOf(value) == i && s.indexOf(value,i+1) == -1)
return s.charAt(i);
}
return ' ';
}
字母表解法
在关键信息中还有一个是字符串中字符只包含小写字母,因此解法就根据小写字母出现次数来判断结果。
- 可以创建一个26大小数组存放每个字符出现次数。
- 遍历字符串记录出现字符次数。
- 再次遍历字符串找到字符次数出现为1的值。
int[] chars = new int[26];
for (int i = 0; i < s.length(); i ++) chars[s.charAt(i) - 'a'] ++;
for (int i = 0; i < s.length(); i ++) {
if (chars[s.charAt(i) - 'a'] == 1) return s.charAt(i);
}
return ' ';
参考
- 来源:力扣(LeetCode)