← 筆記

[LeetCode刷題筆記] 916 – Word Subsets

題目描述:

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 a, including 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 B, b is a subset of a.

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

Example 1:

Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","o"]
Output: ["facebook","google","leetcode"]

Example 2:

Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["l","e"]
Output: ["apple","google","leetcode"]

Example 3:

Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","oo"]
Output: ["facebook","google"]

Example 4:

Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["lo","eo"]
Output: ["google","leetcode"]

Example 5:

Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["ec","oc","ceo"]
Output: ["facebook","leetcode"]

Note:

  1. 1 <= A.length, B.length <= 10000
  2. 1 <= A[i].length, B[i].length <= 10
  3. A[i] and B[i] consist only of lowercase letters.
  4. All words in A[i] are unique: there isn’t i != j with A[i] == A[j].

一刷題解(Brute Force):

這題給了我們兩個字符串數組,A字符串數組裡的都是一些完整的字符串,而B字符串數組裡則都是一些字符碎片,題目要我們在A字符串數組中找到一些字符串,這些字符串中各類字母,包含且大於B字符串中的各類字母出現的最大數量。

因此,我們可以先統計B字符串數組中,各類字母出現的最大次數,並將其放到一個容量為26的數組裡(發揮字母出現次數字典的功能)。完成B的統計後,我們再逐一統計每個A字符串裡,出現的字母是否包括了B字符串的字母,出現次數是否大於B字符串字母的出現次數,如果兩者答案均為肯定,那就代表這個A字符串是我們的其中一個答案。

public class Solution {
    public IList<string> WordSubsets(string[] A, string[] B)
    {
        List<string> result = new List<string>();

        //字母出現統計數組
        int[] charAppearCnt = new int[26];


        //統計B中的字符裡的每類字母出現的最大數量
        for (int i = 0; i < B.Length; i++)
        {
            int[] cntArr = CharCount(B[i]);

            for (int j = 0; j < cntArr.Length; j++)
            {
                if (cntArr[j] == 0) { continue; }
                if (charAppearCnt[j] < cntArr[j])
                {
                    charAppearCnt[j] = cntArr[j];
                }
            }
        }


        //檢查A中的字符的各類字母是包含且大於字典裡的記錄
        for (int i = 0; i < A.Length; i++)
        {
            bool isUniversal = true;
            int[] cntArr = CharCount(A[i]);

            for (int j = 0; j < cntArr.Length; j++)
            {
                //只需要檢查B字符串裡存在的字母,其他沒出現過的字母跳過檢查
                if (charAppearCnt[j] == 0) { continue; }
                //如果A中字母出現次數少於B字符字母的出現次數,該字符B就不是字符A的Subset
                if (cntArr[j] < charAppearCnt[j])
                {
                    isUniversal = false;
                    break;
                }
            }

            if (isUniversal)
            {
                result.Add(A[i]);
            }
        }

        return result;
    } 
    
    int[] CharCount(string str)
    {
        int[] cntArr = new int[26];
        foreach (char c in str.ToCharArray())
        {
            cntArr[c - 'a'] += 1;
        }
        return cntArr;
    }
}