算法之dict

字典的本质:
    其内部是一个数组
    将 key 通过一个hash function 计算出一个整数, 让后将计算出一个整数%数组长度求余
    得出index, 将value存入该index对应的地址中

    set 只有key, 没有value的dict.
    对于dict, 所有的操作的时间复杂度都是O(1), 但是空间复杂度为O(n)

    对于题目中出现:
        计数
        有没有出现过(set)
        有没有重复
    以上字眼可以考虑使用dict
    dict中可存入 <key, 次数> 和 <key, 索引>

1. 计数字符串中字符出现的次数
    def letter_count(s):
        freq = {}
        for i in s:
            if i.isalpha():
                freq[i] = 1 + freq.get(i, 0)
        return freq

2. 找出字符串中字符出现次数最大的字符
    思路: 先计算, 再遍历

    def max_letter_count(s):
        freq = {}
        for i in s:
            if i.isalpha():
                freq[i] = 1 + freq.get(i, 0)
        max_count = 0
        max_letter = 0
        for key, val in freq.items():
            if val > max_count:
                max_count = val
                max_letter = key
        return max_letter,max_count

3. 找出字符串第一个没有重复出现的字符,并返回字符所在是位置(索引)
    如: s = 'givenastring' 字符v是第一没有重复的字符, 所以
    思路: 先使用dict对字符串中每一个字符计数
         然后遍历字符串, 当该字符出现的次数为1时,则返回索引
    def first_unqie_letter(s):
        freq = {}
        for i in s:
            if i.isalpha():
                freq[i] = 1 + freq.get(i, 0) # 计数
        for i in range(len(s)):
            if freq.get(s[i]) == 1: # 出现1则返回
                return i
        return -1

4. 找出两个数组中的公共元素
    思路: 将数组1存入set中, 遍历数组2, 判断每一个元素是否在数组1中出现过
    def intersection(arra1, arra2):
        a1 = set(arra1)
        ret = []
        for i in arra2:
            if i in a1:
                ret.append(i)
        return ret

    使用python中set的特性, 一句代码: set(arra1) & set(arra2)

5. 计数字符串s1中的字符在字符串s2出现的次数和
    比如: s1 = 'aA' s2 = 'aAAbbb' 输出 3
         s1 = 'z' s2 = 'ZZ' 输出 0
    思路: 暴力解法, 两层for循环
    def count_letter(s1, s2):
        count=0
        for i in s1:
            for j in s2:
                if i == j:
                    count += 1
        return count
    使用set降低时间复杂度
    def count_letter(s1, s2):
        count=0
        s = set(s1)
        for i in s2:
            if i in s:
                count += 1
        return count

6. 判断一个字符串中是否有重复的字符
    思路1: 将字符串放入set后的长度和字符串的长度将那些比较是否相等
    def is_contains_duplicate(s):
        return not (len(s) == len(set(s)))

    思路2: 使用dict存储key,count, 出现count = 2,则返回False
    def is_contains_duplicate(s):
        d = {}
        for index, value in enumerate(s):
            # 对于一边存储一边判断(累计求值, 比如求和等)的,一定要先进行存储, 再进行判断
            d[value] = 1 if value not in d else d[value] + 1
            if value in d and d.get(value) >= 2:
                return True
        return False

7. 判断一个字符串中是否有重复的字符, 并且重复字符所在索引的差小于等于k
    思路: for 循环时借助dict进行判断, 如果再dict不存在则存入,
        如果存在则进行判断
    def is_contain_duplicate(s, k):
        d = {}
        for idx, val in enumerate(s):
            if val in d and (idx - d.get(val)) >= k:
                return True
            else:
                # 判断是否存在val, 如果不进行判断对 s='aaba' ,k = 3这样的则有问题
                if val not in d:
                    d[val] = idx
        return False

 

posted @ 2020-04-12 22:42  ilovetesting  阅读(240)  评论(0编辑  收藏  举报