题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
思路
我使用的是LinkedHashMap的数据结构,因为HashMap是无序的,这个是有序的
import java.util.LinkedHashMap;
public class Solution {
LinkedHashMap<Character,Boolean> charhashmap = new LinkedHashMap<>();
//Insert one char from stringstream
public void Insert(char ch)
{
if(charhashmap.get(ch) == null){
charhashmap.put(ch,false);
}else{
charhashmap.put(ch,true);
}
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
for(Character c:charhashmap.keySet()){
if(!charhashmap.get(c)){
return c;
}
}
return '#';
}
}
思路二:
看了CYC大神写的代码,使用了一个256的int数组,还有一个队列用来保证,队列的头部始终是无重复出现的第一个字符,
import java.util.Queue;
import java.util.LinkedList;
public class Solution {
int[] arr = new int[256];
Queue<Character> qq = new LinkedList<>();
//Insert one char from stringstream
public void Insert(char ch)
{
arr[ch]++;
qq.add(ch);
//这样来保证队列最顶端的字符是只出现一次的
while(!qq.isEmpty()&&arr[qq.peek()] > 1){
qq.poll();
}
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
//怎么保证先找出第一个只出现一次的字符
//CYC用一个队列来维持
if(!qq.isEmpty()){
return qq.peek();
}else{
return '#';
}
}
}
LeetCode387 也有类似的题
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
案例:
s = “leetcode”
返回 0.
s = “loveleetcode”,
返回 2.
注意事项:您可以假定该字符串只包含小写字母。
思路:
1.LinkedHashMap
时间复杂度O(n),空间复杂度O(n)
class Solution {
LinkedHashMap<Character,Obb> charhashmap = new LinkedHashMap<>();
class Obb{
boolean check = false;
int index;
Obb(int i){
index = i;
}
}
public int firstUniqChar(String s) {
char[] arrs = s.toCharArray();
for(int i = 0;i < arrs.length;i++){
Insert(arrs[i],i);
}
return FirstAppearingOnce();
}
//Insert one char from stringstream
public void Insert(char ch,int i)
{
if(charhashmap.get(ch) == null){
Obb ob = new Obb(i);
charhashmap.put(ch,ob);
}else{
Obb ob = new Obb(i);
ob.check = true;
charhashmap.put(ch,ob);
}
}
//return the first appearence once char in current stringstream
public int FirstAppearingOnce()
{
for(Character c:charhashmap.keySet()){
if(!charhashmap.get(c).check){
return charhashmap.get(c).index;
}
}
return -1;
}
}
思路2:
看到别人的代码,由于输入的字符都是小写字母,所以使用了一个大小26的数组,里面存储的是索引
时间复杂度是O(n),空间复杂度是O(1)
class Solution {
int[] check = new int[26];
public int firstUniqChar(String s) {
char[] arrs = s.toCharArray();
for(int i = 0;i < arrs.length;i++){
if(check[arrs[i] - 'a'] != 0){
check[arrs[i] - 'a'] = -1;
}else{
check[arrs[i]-'a'] = i + 26;
}
}
return FirstAppearingOnce();
}
//return the first appearence once char in current stringstream
public int FirstAppearingOnce()
{
int min = Integer.MAX_VALUE;
for(int i = 0;i < 26;i++){
if(check[i] == 0 || check[i] == -1)
continue;
else{
if(min > check[i]-26){
min = check[i] - 26;
}
}
}
if(min == Integer.MAX_VALUE)
return -1;
else
return min;
}
}