2306. 公司命名
题目描述
给你一个字符串数组 ideas 表示在公司命名过程中使用的名字列表。公司命名流程如下:
- 从 
ideas中选择 2 个 不同 名字,称为ideaA和ideaB。 - 交换 
ideaA和ideaB的首字母。 - 如果得到的两个新名字 都 不在 
ideas中,那么ideaA ideaB(串联ideaA和ideaB,中间用一个空格分隔)是一个有效的公司名字。 - 否则,不是一个有效的名字。
 
返回 不同 且有效的公司名字的数目。
示例 1:
输入:ideas = ["coffee","donuts","time","toffee"]
输出:6
解释:下面列出一些有效的选择方案:
- ("coffee", "donuts"):对应的公司名字是 "doffee conuts" 。
- ("donuts", "coffee"):对应的公司名字是 "conuts doffee" 。
- ("donuts", "time"):对应的公司名字是 "tonuts dime" 。
- ("donuts", "toffee"):对应的公司名字是 "tonuts doffee" 。
- ("time", "donuts"):对应的公司名字是 "dime tonuts" 。
- ("toffee", "donuts"):对应的公司名字是 "doffee tonuts" 。
因此,总共有 6 个不同的公司名字。
下面列出一些无效的选择方案:
- ("coffee", "time"):在原数组中存在交换后形成的名字 "toffee" 。
- ("time", "toffee"):在原数组中存在交换后形成的两个名字。
- ("coffee", "toffee"):在原数组中存在交换后形成的两个名字。
示例 2:
输入:ideas = ["lack","back"] 输出:0 解释:不存在有效的选择方案。因此,返回 0 。
提示:
2 <= ideas.length <= 5 * 1041 <= ideas[i].length <= 10ideas[i]由小写英文字母组成ideas中的所有字符串 互不相同
解法
方法一:枚举计数
我们定义 \(f[i][j]\) 表示 \(\textit{ideas}\) 中以第 \(i\) 个字母开头,替换为第 \(j\) 个字母后,不在 \(\textit{ideas}\) 中的字符串的个数。初始时 \(f[i][j] = 0\)。另外,用一个哈希表 \(s\) 记录 \(\textit{ideas}\) 中的字符串,方便我们快速判断某个字符串是否在 \(\textit{ideas}\) 中。
接下来,我们遍历 \(\textit{ideas}\) 中字符串,对于当前遍历到的字符串 \(v\),我们枚举替换后的第一个字母 \(j\),如果 \(v\) 替换后的字符串不在 \(\textit{ideas}\) 中,那么我们就更新 \(f[i][j] = f[i][j] + 1\)。
最后,我们再次遍历 \(\textit{ideas}\) 中字符串,对于当前遍历到的字符串 \(v\),我们枚举替换后的第一个字母 \(j\),如果 \(v\) 替换后的字符串不在 \(\textit{ideas}\) 中,那么我们就更新答案 \(\textit{ans} = \textit{ans} + f[j][i]\)。
最终答案即为 \(\textit{ans}\)。
时间复杂度 \(O(n \times m \times |\Sigma|)\),空间复杂度 \(O(|\Sigma|^2)\)。其中 \(n\) 和 \(m\) 分别是 \(\textit{ideas}\) 中字符串的个数和字符串的最大长度,而 \(|\Sigma|\) 是字符串中出现的字符集,本题中 \(|\Sigma| \leq 26\)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  |  | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  |  | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27  |  | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29  |  |