给你一个字符串数组 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 * 104
1 <= ideas[i].length <= 10
ideas[i]
由小写英文字母组成ideas
中的所有字符串 互不相同
方法一:枚举计数
class Solution:
def distinctNames(self, ideas: List[str]) -> int:
s = set(ideas)
f = [[0] * 26 for _ in range(26)]
for v in ideas:
i = ord(v[0]) - ord('a')
t = list(v)
for j in range(26):
t[0] = chr(ord('a') + j)
if ''.join(t) not in s:
f[i][j] += 1
ans = 0
for v in ideas:
i = ord(v[0]) - ord('a')
t = list(v)
for j in range(26):
t[0] = chr(ord('a') + j)
if ''.join(t) not in s:
ans += f[j][i]
return ans
class Solution {
public long distinctNames(String[] ideas) {
Set<String> s = new HashSet<>();
for (String v : ideas) {
s.add(v);
}
int[][] f = new int[26][26];
for (String v : ideas) {
char[] t = v.toCharArray();
int i = t[0] - 'a';
for (int j = 0; j < 26; ++j) {
t[0] = (char) (j + 'a');
if (!s.contains(String.valueOf(t))) {
++f[i][j];
}
}
}
long ans = 0;
for (String v : ideas) {
char[] t = v.toCharArray();
int i = t[0] - 'a';
for (int j = 0; j < 26; ++j) {
t[0] = (char) (j + 'a');
if (!s.contains(String.valueOf(t))) {
ans += f[j][i];
}
}
}
return ans;
}
}
class Solution {
public:
long long distinctNames(vector<string>& ideas) {
unordered_set<string> s(ideas.begin(), ideas.end());
vector<vector<int>> f(26, vector<int>(26));
for (auto v : ideas) {
int i = v[0] - 'a';
for (int j = 0; j < 26; ++j) {
v[0] = j + 'a';
if (!s.count(v)) {
++f[i][j];
}
}
}
long long ans = 0;
for (auto v : ideas) {
int i = v[0] - 'a';
for (int j = 0; j < 26; ++j) {
v[0] = j + 'a';
if (!s.count(v)) {
ans += f[j][i];
}
}
}
return ans;
}
};
func distinctNames(ideas []string) int64 {
s := map[string]bool{}
for _, v := range ideas {
s[v] = true
}
f := make([][]int, 26)
for i := range f {
f[i] = make([]int, 26)
}
for _, v := range ideas {
i := int(v[0] - 'a')
t := []byte(v)
for j := 0; j < 26; j++ {
t[0] = 'a' + byte(j)
if !s[string(t)] {
f[i][j]++
}
}
}
var ans int64
for _, v := range ideas {
i := int(v[0] - 'a')
t := []byte(v)
for j := 0; j < 26; j++ {
t[0] = 'a' + byte(j)
if !s[string(t)] {
ans += int64(f[j][i])
}
}
}
return ans
}