2306.Naming a Company === ###### tags: `Hard`,`Array`,`String`,`Hash Table`,`Bit Manipulation` [2306. Naming a Company](https://leetcode.com/problems/naming-a-company/) ### 題目描述 You are given an array of strings `ideas` that represents a list of names to be used in the process of naming a company. The process of naming a company is as follows: Choose 2 **distinct** names from `ideas`, call them `ideaA` and `ideaB`. Swap the first letters of `ideaA` and `ideaB` with each other. If **both** of the new names are not found in the original `ideas`, then the name `ideaA` `ideaB` (the **concatenation** of `ideaA` and `ideaB`, separated by a space) is a valid company name. Otherwise, it is not a valid name. Return *the number of **distinct** valid names for the company.* ### 範例 **Example 1:** ``` Input: ideas = ["coffee","donuts","time","toffee"] Output: 6 Explanation: The following selections are valid: - ("coffee", "donuts"): The company name created is "doffee conuts". - ("donuts", "coffee"): The company name created is "conuts doffee". - ("donuts", "time"): The company name created is "tonuts dime". - ("donuts", "toffee"): The company name created is "tonuts doffee". - ("time", "donuts"): The company name created is "dime tonuts". - ("toffee", "donuts"): The company name created is "doffee tonuts". Therefore, there are a total of 6 distinct company names. The following are some examples of invalid selections: - ("coffee", "time"): The name "toffee" formed after swapping already exists in the original array. - ("time", "toffee"): Both names are still the same after swapping and exist in the original array. - ("coffee", "toffee"): Both names formed after swapping already exist in the original array. ``` **Example 2:** ``` Input: ideas = ["lack","back"] Output: 0 Explanation: There are no valid selections. Therefore, 0 is returned. ``` **Constraints**: * 2 <= `ideas.length` <= 5 * 10^4^ * 1 <= `ideas[i].length` <= 10 * `ideas[i]` consists of lowercase English letters. * All the strings in `ideas` are **unique**. ### 解答 #### C++ ```cpp= class Solution { public: long long distinctNames(vector<string>& ideas) { unordered_set<string> groups[26]; for (const auto& idea : ideas) { groups[idea[0] - 'a'].insert(idea.substr(1)); } long long ans = 0; for (int i = 0; i < 25; i++) { for (int j = i + 1; j < 26; j++) { long long overlap = 0; for (const auto& word: groups[i]) { overlap += groups[j].count(word); } ans += 2 * (groups[i].size() - overlap) * (groups[j].size() - overlap); } } return ans; } }; ``` > [name=Yen-Chi Chen][time=Thu, Feb 9, 2023] ##### 思路: 1. 選兩個idea, 交換第一個char, 若交換後的單字沒出現在原本的輸入即為合法名字, 找出所有合法名字的數量 2. 交換後若有跟輸入重複者, 代表兩個idea第二個字元後開始後綴一樣 3. 可以第一個字元做分組, 每兩組比較個數, 扣除一樣的後綴數量相乘即此兩組可形成的合法數量 Time: $O(n*m)$ `m`為平均idea長度, 共有`26*25/2=325`個pair group比較, 每個pair group比較花$O(n*m)$ Extra Space: $O(n*m)$ > [name=XD] [time= Feb 9, 2023] #### Python ```python= class Solution: def distinctNames(self, ideas: List[str]) -> int: groups = [set() for _ in range(26)] for idea in ideas: groups[ord(idea[0]) - ord('a')].add(idea[1:]) ans = 0 for i in range(25): for j in range(i + 1, 26): overlap = len(groups[i] & groups[j]) ans += 2 * (len(groups[i]) - overlap) * (len(groups[j]) - overlap) return ans ``` > [name=Yen-Chi Chen][time=Thu, Feb 9, 2023] ### Reference [回到題目列表](https://hackmd.io/@Marsgoat/leetcode_every_day)