welcome to my blog
剑指offer面试题牛客_字符串_字符流中第一个不重复的字符(java版):
题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
思路
- ascii码一共128个, 空格是第一个能输入的字符, 对应的ascii是32
- 创建一个长度为128的数组,根据ascii码统计字符出现的次数 ch - ’ ’ + 32就是字符ch对应的ascii码
- 出现过一次的字符append到sb中, 重复出现的字符不再添加到sb中,但是仍会增加出现次数
- 遍历sb的字符, 返回出现次数为1的字符
第三次做, 提到字符就要想到只有128个, 实际上其中只有32到127这95个是非控制字符, 可以创建一个长为95的数组记录次数; 还要创建的变量记录位置, 使用StringBuilder比链表方便; 本题就是想要清楚怎么记录次数以及怎么记录位置
public class Solution {
//Insert one char from stringstream
int[] arr = new int[128]; //记录次数
StringBuilder sb = new StringBuilder();//记录位置
public void Insert(char ch)
{
sb.append(ch);
arr[ch]++;
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
for(int i=0; i<sb.length(); i++){
if(arr[sb.charAt(i)]==1)
return sb.charAt(i);
}
return '#';
}
}
第二次做, 使用长度为95的数组代替哈希表
import java.util.LinkedList;
public class Solution {
//Insert one char from stringstream
//32~126是非控制字符, 共95个
//数组中索引0记录空格出现的次数
char[] arr = new char[95];
LinkedList<Character> ll = new LinkedList<>();
public void Insert(char ch)
{
//每个字符的索引都是固定的
int index = ch - ' ' ;
arr[index]++;
ll.add(ch);
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
if(ll.isEmpty())
return '#';
while(! ll.isEmpty()){
int index = ll.peek() - ' ';
if(arr[index]==1)
return ll.peek();
ll.poll();
}
//队列中没有只出现一次的字符
return '#';
}
}
第二遍做, 创建一个队列一个哈希表,队列保存出现一次的字符,哈希表记录字符出现的次数; 这个方法空间消耗比较大, 其实可以利用字符种类有限(128个?)的特点,使用数组记录次数
import java.util.LinkedList;
import java.util.HashMap;
public class Solution {
//Insert one char from stringstream
public LinkedList<Character> q = new LinkedList<>();
public HashMap<Character, Integer> hm = new HashMap<>();
public void Insert(char ch)
{
if(hm.containsKey(ch)){
hm.put(ch, hm.get(ch)+1);
if(q.contains(ch))
q.remove(q.indexOf(ch));
}
else{
hm.put(ch, 0);
q.add(ch);
}
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
return q.isEmpty() ? '#' : q.peek();
}
}
import java.util.ArrayList;
public class Solution {
int[] arr = new int[128]; // 利用了默认初始化为0的特点
StringBuffer sb = new StringBuffer();
//Insert one char from stringstream
public void Insert(char ch)
{
int index = ch - ' ' + 32;
arr[index]++;
if(arr[index]==1)
sb.append(ch);
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
if(sb.length() == 0 ) return '#';
int index;
for(int i=0; i<sb.length(); i++){
index = sb.charAt(i) - ' ' + 32;
if(arr[index]==1)
return sb.charAt(i);
}
return '#';
}
}