给你一个字符串数组 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());
int f[26][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) (ans int64) {
s := map[string]bool{}
for _, v := range ideas {
s[v] = true
}
f := [26][26]int{}
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]++
}
}
}
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
}
function distinctNames(ideas: string[]): number {
const s = new Set(ideas);
const f: number[][] = Array(26)
.fill(0)
.map(() => Array(26).fill(0));
for (const v of s) {
const i = v.charCodeAt(0) - 'a'.charCodeAt(0);
const t = [...v];
for (let j = 0; j < 26; ++j) {
t[0] = String.fromCharCode('a'.charCodeAt(0) + j);
if (!s.has(t.join(''))) {
f[i][j]++;
}
}
}
let ans = 0;
for (const v of s) {
const i = v.charCodeAt(0) - 'a'.charCodeAt(0);
const t = [...v];
for (let j = 0; j < 26; ++j) {
t[0] = String.fromCharCode('a'.charCodeAt(0) + j);
if (!s.has(t.join(''))) {
ans += f[j][i];
}
}
}
return ans;
}