> 题目要求
链接:https://www.nowcoder.com/questionTerminal/00de97733b8e4f97a3fb5c680ee10720?answerType=1&f=discussion
来源:牛客网
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输入:如果当前字符流没有存在出现一次的字符,返回#字符。
## 思路分析 ##
1、Insert方法的作用
我们在每次插入一个字符char的时候,就把其累加到字符串input上,并且借助map比较这个字符串是否已经存在于map中(map的key是字符串,value是这个字符串出现的次数)
- 如果本身map中无这样一个key,就把key设置进去,且value=1
- 如果本身map中有这样一个key,就把key更新,在原来的次数上加1;
2、FirstAppearingOnce方法
- 我们先造一个ArrayList筛选存储map中出现的次数为1(即value=1)的key
- 借助拿到的每一个出现1次的key,借助原始输入的字符合并成的字符串,判断该key出现在字符串的位置。
+ 如果该字符的索引最小,那么这个值就是需要返回的值、
完整代码如下:
1 import java.util.*; 2 3 public class Solution { 4 String input = ""; 5 HashMap<Character,Integer> map = new HashMap<>(); 6 7 //把插入的值放入到input串中,并把次数记录在hashMap中 8 //Insert one char from stringstream 9 public void Insert(char ch) 10 { 11 Set keys = map.keySet(); 12 boolean contains = keys.contains(ch); 13 //如果map中没这个键,就加入 14 if (!contains){ 15 map.put(ch,1);//指定该键是ch,值是1 16 input += ch; 17 }else { 18 int value = map.get(ch); 19 value++; 20 map.put(ch,value); //之前有这个key的话就更新 21 input += ch; 22 } 23 } 24 25 //思想:把map中出现次数是1的结果拿如list中,借助input的输入的string,筛选出最前边的字符 26 //return the first appearence once char in current stringstream 27 public char FirstAppearingOnce(){ 28 //暂存结果 29 ArrayList<Character> lis = new ArrayList<>(); 30 //筛选出出现1次的信息放入list 31 for(Map.Entry<Character,Integer> entry:map.entrySet()){ 32 char key = entry.getKey(); 33 Integer value = entry.getValue(); 34 if (value==1){ 35 lis.add(key); 36 } 37 } 38 39 //因为集合map是无序的,索引我们需要借助input字符串来确定哪个字符出现1次且在最前边 40 int minIndex = Integer.MAX_VALUE;//默认是一个很大的索引值 41 if (lis.isEmpty()){ 42 return '#'; 43 }else { 44 for (int i = 0; i < lis.size(); i++) { 45 int index = input.indexOf(lis.get(i)); 46 if (index<minIndex){ 47 minIndex = index; 48 } 49 } 50 return input.toCharArray()[minIndex]; 51 } 52 } 53 }
方法2:借助LinkedHashMap来解决(是顺序存入的)
import java.util.*; class Solution { public char firstUniqChar(String s) { LinkedHashMap<Character,Integer> linkedHashMap = new LinkedHashMap<Character,Integer>(); //1 把字符串按照key为字符,value为次数装入有序的hashMap char[] chars = s.toCharArray(); for (char aChar : chars) { boolean b = linkedHashMap.containsKey(aChar); if (!b){ linkedHashMap.put(aChar,1); }else { Integer integer = linkedHashMap.get(aChar); integer++; linkedHashMap.put(aChar,integer); } } //2 直接从LinkedHashMap中拿到第一个value为1 的字符即可。 Iterator<Map.Entry<Character, Integer>> iterator = linkedHashMap.entrySet().iterator(); while (iterator.hasNext()){ Map.Entry<Character, Integer> entry = iterator.next(); if (entry.getValue()==1){ return entry.getKey(); }else { continue; } } //3 走出while循环,没返回的话,就返回未找到 return ' '; } } 作者:beibicoder666 链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/zi-fu-liu-zhong-di-yi-ge-bu-zhong-fu-de-zi-fu-by-b/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。