JZ54 字符流中第一个不重复的字符
字符流中第一个不重复的字符
http://www.nowcoder.com/questionTerminal/00de97733b8e4f97a3fb5c680ee10720
解法一: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();
}
}