2306 - 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 themideaA
andideaB
. - Swap the first letters of
ideaA
andideaB
with each other. - If both of the new names are not found in the original
ideas
, then the nameideaA ideaB
(the concatenation ofideaA
andideaB
, 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.
說明
我自己先想了一個解法:
先把資料處理成 map: idea[0] -> set of idea[1:]
, 然後就可以發現任兩個【第一個字元】所做出的 valid company name 會是
Tips:
- 要對
idea[1:]
做離散化,減少set<idea[1:]>
的操作常數。 - 計算
set1 - set2
時,可以只迭代較小的set
。
不過後來我看題解是有用另外的解法。我把問題切成 (i, j)
互換,題解再切了一半:只考慮 i → j
的情況,也就是去數多少個 i 可以換到 j 。最後只要把 (|i→j||j→i|)
加起來就好。
Tips:
- 可以用
std::string_view
Code: 我的作法
cpp
class Solution {
public:
long long distinctNames(vector<string>& ideas) {
// 離散化
map<string, int> strIdx;
for (const auto& s: ideas) {
auto suffix = s.substr(1);
if (strIdx.count(suffix)) {
continue;
}
strIdx[suffix] = strIdx.size();
}
vector<set<int>> headTail(26);
for (const auto& s: ideas) {
headTail[s[0] - 'a'].insert(strIdx[s.substr(1)]);
}
int64_t ans = 0;
for (int lx = 0; lx < 26; ++lx) {
for (int ly = lx+1; ly < 26; ++ly) {
ans += count(headTail[lx], headTail[ly])*2;
}
}
return ans;
}
private:
int64_t count(const set<int>& a, const set<int>& b) {
int64_t sz1 = a.size();
int64_t sz2 = b.size();
if (sz1 > sz2) {
for (const auto& s: b) {
if (a.find(s) != a.end()) {
--sz1;
--sz2;
}
}
} else {
for (const auto& s: a) {
if (b.find(s) != b.end()) {
--sz1;
--sz2;
}
}
}
return sz1*sz2;
}
};
Code: 題解
cpp
class Solution {
public:
long long distinctNames(vector<string>& ideas) {
unordered_set<string_view> ideasSet(ideas.begin(), ideas.end());
vector<vector<int>> tab(26, vector<int>(26, 0));
for (const auto& idea: ideas) {
int i = idea[0] - 'a';
string tmp = idea;
for (int j = 0; j < 26; ++j) {
tmp[0] = 'a' + j;
if (ideasSet.find(tmp) == ideasSet.end()) {
++tab[i][j];
}
}
}
int64_t ans = 0;
for (int i = 0; i < 26; ++i) {
for (int j = 0; j < 26; ++j) {
ans += int64_t(tab[i][j])*tab[j][i];
}
}
return ans;
}
};