找到第一个只出现一次的字符 python

面试常考题,最近几天滴滴和百度都被问过.

机智如我第一时间想到的最蠢的方法就是,遍历字符串,判断当前字符是否在后面的字符串中出现。


def first_uniq(s):
    for i in range(len(s)):
        if s[i] not in s[i+1:]:
            return(s[i])

这样写,时间复杂度O( n2),而且‘aaaaaaaaaaaaabc’这种字符串会返回‘a'。真是蠢啊,排个序再遍历判断s[i] !=s[i+1]都比这个强。


然后自然想到用字典统计一下每个字符出现的次数,节省点儿行数用了collections 中的defaultdict。

def first_uniq(s):
    cnter = defaultdict(lambda:0)
    for i in s:
        cnter[i] += 1
    for i in s:
        if cnter[i] == 1:
            return i

但是还是需要loop 2次。



*************** 后面这俩不大好 想到好的方法再改 “如果别的语言没有OrderedDict数据类型怎么办,自己复写一个?”****************


限制只执行一次loop怎么办,因为字典是无序,其实只需要在我们的字典里维护一个‘字符’出现顺序就可以了,自然想到了OrderedDict.

def first_uniq(s):
    cnter = OrderedDict()
    for i in s:
        if i in cnter:
            cnter.move_to_end(i)
            cnter[i] += 1
        else:
            cnter[i] = 1
    return list(cnter)[0]

那么问题又出现了,只有最后一个数只出现一次,如‘abcabcabch’这种输入的时候还是会有问题。return的时候做一下判断, 或者再维护一个字典。

    cnt_list = list(cnter)
    if cnt_list[0] == 1:
        return cnt_list[0]
    elif cnt_list[-1] == 1:
        return cnt_list[-1]
    else:
        return None

def first_uniq(s):
    cnter_1 = OrderedDict()
    cnter_other = OrderedDict()
    for i in s:
        if i in cnter_other:
            cnter_other[i] += 1
        elif i in cnter_1:
            cnter_1.pop(i)
            cnter_other[i] = 2
        else:
            cnter_1[i] = 1
    if cnter_1:
        return list(cnter_1)[0]
    else:
        return None



猜你喜欢

转载自blog.csdn.net/be5yond/article/details/74391203