解法一:HashMap+ArrayList
基本思路
- 用HashSet记录出现过至少一次的值,用ArrayList记录只出现过一次的值。
- insert每次在HashSet中查找 ch,如果没有,那么就往ArrayList中添加;如果有,就从ArrayList中删除 ch。(可能出现ArrayList中已经没有ch但依然要删除的情况,这是没有关系的,找不到ch, remove()会返回false)
- ArrayList中一定是按顺序存储着只出现过一次的值,那么每次FirstAppearingOnce()只用返回在ArrayList首位的字符即可。如果ArrayList为空,那么就返回'#'。
注意
list.remove((Character)ch);
这里的(Character)强制转换不能少,否则,char输入会直接被识别为整型变量。list.remove()就变成了按照位置删除了。
import java.util.*; public class Solution { //Insert one char from stringstream public void Insert(char ch){ if(!once.contains(ch)) { list.add(ch); once.add(ch); } else { list.remove((Character)ch); } } //return the first appearence once char in current stringstream List<Character> list=new LinkedList<>(); Set<Character> once=new HashSet<>(); public char FirstAppearingOnce(){ if(list.size()>0) return list.get(0); return '#'; } }
解法二:HashMap+Queue
这道题的常见做法。
HashMap储存 字符和字符出现次数。(我直接用boolean表示 false:出现过一次, true:出现过一次以上。因为出现2、3、4...次的处理都是一样的,没有必要再往上+1了。)
Queue按顺序储存可能是仅出现过一次的字符,每一次FirstAppearingOnce()返回前要通过HashMap判断。
import java.util.*; public class Solution { //Insert one char from stringstream Map<Character, Boolean> map=new HashMap<>(); Queue<Character> q=new LinkedList<>(); public void Insert(char ch){ if(!map.containsKey(ch)){ q.add(ch); map.put(ch,false); }else{ map.put(ch,true); } } //return the first appearence once char in current stringstream public char FirstAppearingOnce(){ while(!q.isEmpty()&&map.get(q.peek())){ q.poll(); } return q.isEmpty()? '#':q.peek(); } }