一道演算法題,引出collections.Counter的特殊用法

Bigyoungs發表於2020-10-14

題目描述:

題目編號:1002. 查詢常用字元

給定僅有小寫字母組成的字串陣列 A,返回列表中的每個字串中都顯示的全部字元(包括重複字元)組成的列表。例如,如果一個字元在每個字串中出現 3 次,但不是 4 次,則需要在最終答案中包含該字元 3 次。

你可以按任意順序返回答案。
 

示例 1:

輸入:["bella","label","roller"]
輸出:["e","l","l"]
示例 2:

輸入:["cool","lock","cook"]
輸出:["c","o"]
 

提示:
1 <= A.length <= 100
1 <= A[i].length <= 100
A[i][j] 是小寫字母

以上內容來源:力扣(LeetCode)連結:https://leetcode-cn.com/problems/find-common-characters

題目答案:

from collections import Counter

class Solution:
    def commonChars(self, A: List[str]) -> List[str]:
        res = None
        for a in A:
            c = Counter(a)
            if res is None:
                res = c
            else:
                res &= c
        return list(res.elements())
        
題解看到一個一行流,膜拜一下 boille

class Solution:
    def commonChars(self, A: List[str]) -> List[str]:
        return list(reduce(lambda x, y: x & y, map(collections.Counter, A)).elements())

以上內容來源:力扣(LeetCode)連結:https://leetcode-cn.com/problems/find-common-characters/solution/cha-zhao-chang-yong-zi-fu-by-leetcode-solution/
作者:zyyyyy

疑問:

題解中的res &= c是什麼鬼?為什麼能夠達到解題思路中的,得到計數最小的效果?

看了題解下的解答,有人說是&在Counter中,是一種特殊的用法,獲取交接中結果,但是這個解釋不是很清晰,未能打消我的疑惑,所以進行了進一步的研究。

查到了一篇文件:Python計數器collections.Counter用法詳解

最後介紹了Counter的&的用法。

答疑:

res &= c,展開式:res = res & c
Counter特有的算數運算,使用&時,取兩個Counter物件中交集元素計數小的結果。

例子:
Counter('AAB') & Counter('BBCC') 的輸出結果是:{'B': 1}

過程:
第一步:得到元素計數:{'A':2, "B":1} 和 {'B':2,'C':2}
第二步:取交集:{"B":1} & {'B':2}
第三步:得出結果:取計數小的結果:{'B': 1}

本文首發於BigYoung小站

相關文章