1. 程式人生 > >leetcode-916. Word Subsets(單詞子集)

leetcode-916. Word Subsets(單詞子集)

1、題目描述

We are given two arrays A and B of words.  Each word is a string of lowercase letters.

Now, say that word b is a subset of word a if every letter in b occurs in aincluding multiplicity.  For example, "wrr" is a subset of "warrior"

, but is not a subset of "world".

Now say a word a from A is universal if for every b in Bb is a subset of a

Return a list of all universal words in A.  You can return the words in any order.

2、解題分析

以輸入A = ["amazon","apple","facebook","google","leetcode"], B = ["ec","oc","ceo"]為例:

A中單詞要滿足題目要求,必須滿足B中每個詞中字元組成的列表包含在該單詞中。要滿足該要求,該單詞需要包含B中所有詞中字母的並集(不去重)

但能想到的演算法提交都超時了,現在還沒有更好的想法...

3、程式碼

3.1、直接法

1、

# -*- coding: utf-8 -*-
"""
Created on Tue Oct  2 22:49:40 2018

@author: yzp1011
"""
from collections import Counter
import numpy as np
import pandas as pd

class Solution:
    def __init__(self):
        A = ["amazon","apple","facebook","google","leetcode"]
        B = ["ec","oc","ceo"]
        self.wordSubsets(A,B)
        
    def wordSubsets(self, A, B):
        """
        :type A: List[str]
        :type B: List[str]
        :rtype: List[str]
        """
        res = []
        b_df = pd.concat([pd.DataFrame(list(Counter(x).items())).set_index(0) for x in B], axis=1)
        b_df.fillna(0,inplace=True)
        for x in A:
            a_df = pd.DataFrame(list(Counter(x).items())).set_index(0)
            if not a_df.sub(b_df,axis=0,fill_value=0).where(lambda y:y < 0).any().any():
                res.append(x)
        return res


if __name__ == '__main__':
    s = Solution()

2、

# -*- coding: utf-8 -*-
"""
Created on Wed Oct  3 02:09:24 2018

@author: yzp1011
"""
from collections import Counter


class Solution:
    def __init__(self):
        A = ["amazon","apple","facebook","google","leetcode"]
        B = ["ec","oc","ceo"]
        print(self.wordSubsets(A,B))
        
    def wordSubsets(self, A, B):
        """
        :type A: List[str]
        :type B: List[str]
        :rtype: List[str]
        """
        b_dict = [Counter(x) for x in B]
        in_flag = True
        res = []
        for word in A:
            a_dict = Counter(word)
            for b_char_dict in b_dict:
                for k,v in b_char_dict.items():
                    if v > a_dict[k]:
                        in_flag = False
                        break
                if not in_flag:
                    break
            if in_flag:
                res.append(word)
            else:
                in_flag = True
        return res
    

if __name__ == '__main__':
    s = Solution()

3.2、優化演算法

# -*- coding: utf-8 -*-
"""
Created on Wed Oct  3 09:47:50 2018

@author: yzp1011
"""
from operator import ior
from functools import reduce
from collections import Counter


class Solution:
    def __init__(self):
        A = ["amazon","apple","facebook","google","leetcode"]
        B = ["ec","oc","ceo"]
        print(self.wordSubsets(A,B))
        
    def wordSubsets(self, A, B):
        """
        :type A: List[str]
        :type B: List[str]
        :rtype: List[str]
        """
        char_b = reduce(ior, map(Counter, B))        
        return [x for x in A if Counter(x) & char_b == char_b]
    

if __name__ == '__main__':
    s = Solution()