首页 > 试题广场 >

字符流中第一个不重复的字符

[编程题]字符流中第一个不重复的字符
  • 热度指数:322584 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 "go" 时,第一个只出现一次的字符是 "g" 。当从该字符流中读出前六个字符 “google" 时,第一个只出现一次的字符是"l"。

数据范围:字符串长度满足 ,字符串中出现的字符一定在 ASCII 码内。
进阶:空间复杂度 ,时间复杂度

后台会用以下方式调用 Insert 和 FirstAppearingOnce 函数
string caseout = "";
1.读入测试用例字符串casein
2.如果对应语言有Init()函数的话,执行Init() 函数
3.循环遍历字符串里的每一个字符ch {
Insert(ch);
caseout += FirstAppearingOnce()
}
2. 输出caseout,进行比较。

输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
示例1

输入

"google"

输出

"ggg#ll"
示例2

输入

"abcdee"

输出

"aaaaaa"
推荐
利用一个int型数组表示256个字符,这个数组初值置为-1.
没读出一个字符,将该字符的位置存入字符对应数组下标中。
若值为-1标识第一次读入,不为-1且》0表示不是第一次读入,将值改为-2.
之后在数组中找到>0的最小值,该数组下标对应的字符为所求。
public class Solution {
    //Insert one char from stringstream
    private int[] occurence = new int[256];
    private int index;
    
    public Solution(){
        for(int i=0;i<256;i++){
            occurence[i] = -1;
        }
        index = 0;
    }
    void Insert(char ch)
    {
        if(occurence[ch] == -1)
            occurence[ch] = index;
        else if(occurence[ch] >= 0)
            occurence[ch] = -2;
        
        index++;
    }
  //return the first appearence once char in current stringstream
    char FirstAppearingOnce()
    {
        char ch = '\0';
        int minIndex = Integer.MAX_VALUE;
        for(int i=0;i<256;i++){
            if(occurence[i] >=0 && occurence[i]<minIndex){
                ch = (char)i;
                minIndex = occurence[i];
            }
        }
        if(ch == '\0')
            return '#';
        return ch;
    }
}

编辑于 2015-08-18 23:07:59 回复(36)
# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.tmp =''
    def FirstAppearingOnce(self):
        # write code here
        for j in self.tmp:
            if self.tmp.count(j)==1:
                return j
        return '#'
    def Insert(self, char):
        # write code here
        self.tmp += char
发表于 2020-11-29 18:42:36 回复(0)
class Solution:
    def __init__(self):
        self.ListA = []
    def FirstAppearingOnce(self):
        self.dictB = {}
        for i in self.ListA:
            if i not in self.dictB.keys():
                self.dictB[i] = 1
            else:
                self.dictB[i] += 1
        for a in self.ListA:
            if self.dictB[a] == 1:
                return a
        return '#'
    def Insert(self, char):
        self.ListA.append(char)

发表于 2020-08-12 23:06:38 回复(0)
# -*- coding:utf-8 -*-
from collections import Counter
class Solution:
    def __init__(self):
        self.s=''
        #self.dict={} #创建字典,key为读取的字符串中的每一个字符,val为每个字符出现的个数的计数值
    # 返回对应char
    def FirstAppearingOnce(self):
        dic=Counter(self.s)
        for i in dic:
            if dic[i]==1:
                return i
        return "#"
    def Insert(self, char):
        # write code here
        self.s=self.s+char #从字符流中读入字符到字符串s中
为啥显示答案错误啊?
发表于 2020-08-12 15:23:51 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.s = ""
        self.dict = {}
    def FirstAppearingOnce(self):
        for i in self.s:
            if self.dict[i] == 1:
                return i 
        return '#'
    def Insert(self, char):
        # write code here
        self.s = self.s + char
        if char in self.dict :
            self.dict[char] = self.dict[char]+1
        else:
            self.dict[char] = 1
函数Insert()中的char等同于函数FirstAppearingOnce()中的i
编辑于 2020-07-27 16:06:16 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.s = ''
    def FirstAppearingOnce(self):
        # write code here
        for i in self.s:
            if self.s.count(i) == 1:
                return i
        return '#'
    def Insert(self, char):
        # write code here
        self.s += char
            
直接用count函数判断输出
发表于 2020-07-24 16:30:26 回复(0)

# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.num_dict = {}
        self.first = []

    # 返回对应char
    def FirstAppearingOnce(self):
        # write code here
        if len(self.first) == 0:
            return '#'
        else:
            return self.first[0]

    def Insert(self, char):
        # write code here
        if char not in self.num_dict:
            self.num_dict[char] = 1
            self.first.append(char)
        else:
            self.num_dict[char] += 1
            if self.num_dict[char]==2:
                for i in range(len(self.first)):
                    if char==self.first[i]:
                        self.first.pop(i)
                        break
利用一个字典,记录每个字符的数量,一个数组记录为1的字符。插入一个字符,用字典判断该字符的数量,如果字典中不存在该字符,则该字符分别插入字典和数组。如果该字符已经存在,并且数量为1,那么在数组中查找该字符,并且弹出。字典中数量加1


编辑于 2020-06-14 11:45:00 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.outp=''
        self.str1=[]
        self.occured=[]
        self.char=''
    # 返回对应char
    def FirstAppearingOnce(self):
        if self.str1==[]:
            self.str1.append(self.char)
            self.outp=self.char
            return self.outp
        if self.char!=self.outp:
            self.str1.append(self.char)
            return self.outp
        if self.char==self.outp:
            self.str1.append(self.char)           
            for i in range(len(self.str1)):
                c=self.str1.count(self.str1[i])                
                if c==1:
                    self.outp=self.str1[i]                    
                    return self.outp                    
                if i==len(self.str1)-1:
                    self.str1=[]                    
                    return '#'

    def Insert(self, char):
        self.char=char
     
只有当输出发生变化时才寻找下一个第一个出现的字符
发表于 2020-05-28 00:14:34 回复(0)
注意字典是无序的,输出时按照输入的顺序遍历
注意s和d为空的情况


# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.s = []
        
    def FirstAppearingOnce(self):
        # write code here
        if len(self.s) == 0:
            return '#'
        d = dict() #无序字典,不按照输入的顺序
        for x in self.s:
            if x in d:
                d[x] += 1
            else:
                d[x] = 1
        for x in self.s: # 按照输入的顺序查找
            if d[x]==1:
                return x
        return '#'
        
    def Insert(self, char):
        # write code here
        self.s.append(char)


发表于 2020-05-23 12:08:12 回复(0)

运行时间:25ms

占用内存:5848k
对撞指针

发表于 2020-03-21 13:39:25 回复(0)
# -*- coding:utf-8 -*-
"""
空间换时间
"""
class Solution:
    def __init__(self):
        self.data = []

    def FirstAppearingOnce(self):
        """
        Time: O(n)
        space: O(1)
        :return: 
        """
        cnt = {}
        for d in self.data:
            cnt[d] = cnt.get(d,0) + 1
        for d in self.data:
            if cnt[d] == 1:
                return d
        return "#"

    def Insert(self, char):
        self.data.append(char)


s = Solution()
s.Insert("g")
s.Insert("o")
s.Insert("o")
s.Insert("g")
s.Insert("g")
ans = s.FirstAppearingOnce()
print(ans)

编辑于 2020-03-03 08:58:52 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.s=''
        self.dict={} #创建字典,key为读取的字符串中的每一个字符,val为每个字符出现的个数的计数值
    # 返回对应char
    def FirstAppearingOnce(self):
        # write code here
        for i in self.s: #遍历字符串s中的字符
            if self.dict[i]==1: #如果某个字符对应的计数为1,则返回该字符
                return i
        return '#' #在所有字符遍历完后,进行判断
    def Insert(self, char):
        # write code here
        self.s=self.s+char #从字符流中读入字符到字符串s中
        if char in self.dict:
            self.dict[char]=self.dict[char]+1 #如果读入的字符在字符串中已存在,在字典中对应的字符计数加一
        else:
            self.dict[char]=1#如果读入的字符在字符串中不存在,则字典中对应的字符计数为一(即新增了一个新的字符)

本题主要在于理解题意,本题的关键是分两部分,一个是原有字符串的添加,另一个是找到现有字符串中第一次只出现一次的字符
发表于 2020-01-27 21:53:17 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.dict = {}
        self.list = []
    def FirstAppearingOnce(self):
        # write code here
        if len(self.list) == 0:
            return '#'
        else:
            for i in self.list:
                if self.dict[i] == 1:
                    return i
            return '#'
    def Insert(self, char):
        # write code here
        self.list.append(char)
        if char in self.dict:
            self.dict[char] = self.dict[char] + 1
        else:
            self.dict[char] = 1

编辑于 2019-12-23 13:58:40 回复(2)
Insert是读字符,读入之后,统计当前字符串中的字符是否出现次数为1,若为1,则输入该字符;把字符串中的字符判断完之后若没有,则返回#
# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.c = ""
    def FirstAppearingOnce(self):
        for s in self.c:
            if self.c.count(s) == 1:
                return s
        return "#"
    def Insert(self, char):
        self.c = self.c + char  #读入字符到字符串c中

发表于 2019-12-04 21:20:13 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.s = ''
    # 返回对应char
    def FirstAppearingOnce(self):
        # write code here
        ls = list(filter(lambda x: self.s.count(x) == 1, self.s ))
        return ls[0] if ls else '#'
    def Insert(self, char):
        # write code here
        self.s += char
        

发表于 2019-11-29 12:20:08 回复(0)
用一个字典记录字符的次数,同时用一个列表记录字符的顺序(因为字典是无序的
# -*- coding:utf-8 -*-
class Solution():
    # 返回对应char
    def __init__(self):
        self.list01=[]
        self.dict01={}
        
    def FirstAppearingOnce(self):
        for i in self.list01:
            if self.dict01[i]==1:
                return i
        return '#'
    
    def Insert(self, char):
        self.dict01.setdefault(char,0)
        self.dict01[char]+=1
        if char not in self.list01:
            self.list01.append(char)


发表于 2019-11-15 23:30:10 回复(0)
# -*- coding:utf-8 -*-
class Solution:
    # 返回对应char
    def __init__(self):
        self.s = ''
    def FirstAppearingOnce(self):
        # write code here
        for i in range(len(self.s)):
            if self.s.count(self.s[i]) == 1:
                return self.s[i]
        return '#'
        
    def Insert(self, char):
        # write code here
        self.s += char

发表于 2019-09-16 14:37:16 回复(0)
思路:
1.用哈希表记录字符出现的次数
2.用队列存放出现只出现一次的字符。 最后输出队头元素即可
ps: 不管字符流多长,每种字符进入的次数都只有一次。队列的操作时间复杂度O(1)。输出时如果队头次数大于1删除,时刻保持队头即是答案的状态
class Solution:
    def __init__(self):
        self.re=[0 for x in range(129)]
        self.data=[]
    def FirstAppearingOnce(self):
        while self.data :
            f=ord(self.data[0])
            if self.re[f]==1:
                return self.data[0]
            else:
                self.data.pop(0)
        return '#'
    def Insert(self, char):
        d=ord(char)
        self.re[d]+=1
        if self.re[d]==1:
            self.data.append(char)


发表于 2019-09-14 19:16:42 回复(0)
def __init__(self):
    self.s=''
def FirstAppearingOnce(self):
    # write code here
    for i in self.s:
        if self.s.count(i)==1:
            return i
    return '#'
def Insert(self, char):
    # write code here
    self.s+=char

编辑于 2019-08-28 21:07:23 回复(2)
class Solution:
    # 返回对应char
    def __init__(self):
        self.res = []
    def FirstAppearingOnce(self):
        # write code here 
        if not self.res:        #如果res为空 则说明字符流中不存在只出现一次的字符
            return '#'
        return self.res[0]       #return 第一个只出现一次的字符
    def Insert(self, char):
        # write code here
        tmp = self.res
        if char not in tmp:
            tmp.append(char)  #如果tmp中没有这个字符  将字符导入res中
        else:
            tmp.remove(char)   #如果tmp中已经有了该字符 将res中的该字符删除
        self.res = tmp[:]      #深拷贝
我自认位这种方式比书上好理解一点
编辑于 2019-08-13 18:43:02 回复(1)