173-求子集和猜灯谜

先看78,再去看1178,这两道题都比较难
# 78. 子集问题
class Solution(object):
    def subsets(self, nums):
        """
        https://leetcode-cn.com/problems/subsets/solution/zi-ji-by-leetcode-solution/
        :type nums: List[int]
        :rtype: List[List[int]]
        这道题是很经典的位运算问题,将nums中的数字都理解一位1,则nums= [1,2,3] = 111(二进制) = 7(十进制)
        那么nums的子集从最小的[]到[1,2,3]就有
        {}= 000
        {3} = 001
        {2}= 010
        {2,3}= 011
        {1} = 100
        {1, 3}= 101
        {1, 2} = 110
        {1,2,3} = 111 八种
        也就是2**3 = 2 ** len(nums),可以通过&的方式遍历所有子集,代码如下:
        """
        length = len(nums)

        ret_list = []
        # 共有多少种可能,i表示的其实就是他的二进制
        for i in range((1 << length)):
            temp_list = []
            # 每一次循环的j就是nums中的一位数,1 << j 刚好就是他的二进制表示,如果i&(1<<j) = 1
            # 则表示nums[j]在这次的子集中,append即可
            for j in range(length):
                if i & (1 << j):
                    temp_list.append(nums[j])
            ret_list.append(temp_list)
        return ret_list


if __name__ == '__main__':
    s1 = Solution()
    a = [1, 2, 3]
    root = s1.subsets(a)
    print(root)

import collections


# 1178. 猜字谜  先看上面的题再看下面的
class Solution:
    def findNumOfValidWords1(self, words, puzzles):
        counter = collections.Counter()
        for word in words:
            mask = 0
            for c in word:
                mask |= 1 << (ord(c) - ord("a"))
            counter[mask] += 1

        res = []

        for puzzle in puzzles:
            count = 0
            for i in range(1 << 6):
                mask = 0
                for j in range(6):
                    if i & (1 << j):
                        mask |= 1 << (ord(puzzle[j + 1]) - ord("a"))
                mask |= 1 << (ord(puzzle[0]) - ord("a"))
                if mask in counter:
                    count += counter.get(mask)
            res.append(count)
        return res

    def findNumOfValidWords(self, words, puzzles):
        freq = collections.Counter()
        for word in words:
            mask = 0
            for c in word:
                mask |= 1 << (ord(c) - ord('a'))
            freq[mask] += 1
        res = []
        for puzzle in puzzles:
            total = 0
            for perm in self.subsets(puzzle[1:]):
                mask = 1 << (ord(puzzle[0]) - ord('a'))
                for c in perm:
                    mask |= 1 << (ord(c) - ord('a'))
                total += freq[mask]
            res.append(total)
        return res

    def subsets(self, words):
        res = [""]
        for i in words:
            res += [i + word for word in res]
        return res

    def subsets2(self, words):
        res = [""]
        for i in words:
            temp_list = res
            temp_len = len(temp_list)
            for j in range(temp_len):
                res.append(i + temp_list[j])
            temp_list = res
        return res


if __name__ == '__main__':
    words = ["aaaa", "asas", "able", "ability", "actt", "actor", "access"]
    puzzles = ["aboveyz", "abrodyz", "abslute", "absoryz", "actresz", "gaswxyz"]

    s1 = Solution()
    # root = s1.findNumOfValidWords(words, puzzles)
    # print(root)
    print(s1.subsets2("aboveyz"))
    print(s1.subsets("aboveyz"))

posted @ 2021-02-26 15:23  楠海  阅读(77)  评论(0)    收藏  举报