网站域名 "discuss.leetcode.com" 由多个子域名组成。顶级域名为 "com" ,二级域名为 "leetcode.com" ,最低一级为 "discuss.leetcode.com" 。当访问域名 "discuss.leetcode.com" 时,同时也会隐式访问其父域名 "leetcode.com" 以及 "com" 。
计数配对域名 是遵循 "rep d1.d2.d3" 或 "rep d1.d2" 格式的一个域名表示,其中 rep 表示访问域名的次数,d1.d2.d3 为域名本身。
例如,"9001 discuss.leetcode.com" 就是一个 计数配对域名 ,表示 discuss.leetcode.com 被访问了 9001 次。
给你一个 计数配对域名 组成的数组 cpdomains ,解析得到输入中每个子域名对应的 计数配对域名 ,并以数组形式返回。可以按 任意顺序 返回答案。
示例 1:
输入:cpdomains = ["9001 discuss.leetcode.com"]
输出:["9001 leetcode.com","9001 discuss.leetcode.com","9001 com"]
解释:例子中仅包含一个网站域名:"discuss.leetcode.com"。
按照前文描述,子域名 "leetcode.com" 和 "com" 都会被访问,所以它们都被访问了 9001 次。
示例 2:
输入:cpdomains = ["900 google.mail.com", "50 yahoo.com", "1 intel.mail.com", "5 wiki.org"]
输出:["901 mail.com","50 yahoo.com","900 google.mail.com","5 wiki.org","5 org","1 intel.mail.com","951 com"]
解释:按照前文描述,会访问 "google.mail.com" 900 次,"yahoo.com" 50 次,"intel.mail.com" 1 次,"wiki.org" 5 次。
而对于父域名,会访问 "mail.com" 900 + 1 = 901 次,"com" 900 + 50 + 1 = 951 次,和 "org" 5 次。
提示:
1 <= cpdomain.length <= 100
1 <= cpdomain[i].length <= 100
cpdomain[i] 会遵循 "repi d1i.d2i.d3i" 或 "repi d1i.d2i" 格式
repi 是范围 [1, 104] 内的一个整数
d1i、d2i 和 d3i 由小写英文字母组成
var subdomainVisits = function(cpdomains) {
const n = cpdomains.length, h = new Map, r = []
for (let i = 0; i < n; i++) {
let [cnt, domain] = cpdomains[i].split(' ')
h.set(domain, (h.get(domain) || 0) + +cnt)
const m = domain.length
for (let i = 0; i < m; i++) {
if (domain[i] === '.') {
const t = domain.substring(i + 1)
h.set(t, (h.get(t) || 0) + +cnt)
}
}
}
for (const [domain, cnt] of h.entries()) {
r.push(cnt + ' ' + domain)
}
return r
};
var subdomainVisits = function(cpdomains) { // indexOf + subString实现
const n = cpdomains.length, h = new Map, r = []
for (let i = 0; i < n; i++) {
let [cnt, domain] = cpdomains[i].split(' ')
h.set(domain, (h.get(domain) || 0) + +cnt)
while (domain.includes('.')) {
domain = domain.substring(domain.indexOf('.') + 1)
h.set(domain, (h.get(domain) || 0) + +cnt)
}
}
for (const [domain, cnt] of h.entries()) {
r.push(cnt + ' ' + domain)
}
return r
};
var subdomainVisits = function(cpdomains) { // split + slice 实现
const n = cpdomains.length, h = new Map, r = []
for (let i = 0; i < n; i++) {
const [cnt, cpdomain] = cpdomains[i].split(' ')
const domains = cpdomain.split('.')
for (let i = domains.length; i--;) {
const t = domains.slice(-i - 1).join('.')
h.set(t, (h.get(t) || 0) + +cnt)
}
}
for (const [domain, cnt] of h.entries()) {
r.push(cnt + ' ' + domain)
}
return r
};
function subdomainVisits(cpdomains: string[]): string[] {
const n = cpdomains.length, h = new Map, r = []
for (let i = 0; i < n; i++) {
const cpdomain = cpdomains[i]
const spaceIndex = cpdomain.indexOf(' ')
const cnt = +cpdomain.substring(0, spaceIndex)
const domain = cpdomain.substring(spaceIndex + 1)
const m = domain.length
h.set(domain, (h.get(domain) || 0) + cnt)
for (let i = 0; i < m; i++) {
if (domain[i] === '.') {
const t = domain.substring(i + 1)
h.set(t, (h.get(t) || 0) + cnt)
}
}
}
for (const [domain, cnt] of h.entries()) {
r.push(`${cnt} ${domain}`)
}
return r
};
class Solution {
function subdomainVisits($cpdomains) {
$h = [];
foreach ($cpdomains as $cpdomain) {
list($cnt, $domain) = explode(' ', $cpdomain);
$h[$domain] = ($h[$domain] ?? 0) + $cnt;
$m = strlen($domain);
for ($i = 0; $i < $m; $i++) {
if ($domain[$i] === '.') {
$t = substr($domain, $i + 1);
$h[$t] = ($h[$t] ?? 0) + $cnt;
}
}
}
$r = [];
foreach ($h as $domain => $cnt) {
$r []= $cnt . ' ' . $domain;
}
return $r;
}
}
func subdomainVisits(cpdomains []string) []string {
h, r := map[string]int{}, []string{}
for _, cpdomain := range cpdomains {
slice := strings.SplitN(cpdomain, " ", 2)
cnt, _ := strconv.Atoi(slice[0])
domain := slice[1]
h[domain] += cnt
for i, c := range domain {
if c == '.' {
h[domain[i + 1:]] += cnt
}
}
}
for domain, cnt := range h {
r = append(r, strconv.Itoa(cnt) + " " + domain)
}
return r
}
class Solution {
public List<String> subdomainVisits(String[] cpdomains) {
Map<String, Integer> h = new HashMap<String, Integer>();
for (String cpdomain : cpdomains) {
String[] tmp = cpdomain.split(" ", 2);
int cnt = Integer.parseInt(tmp[0]);
String domain = tmp[1];
h.put(domain, h.getOrDefault(domain, 0) + cnt);
int m = domain.length();
for (int i = 0; i < m; i++) {
if (domain.charAt(i) == '.') {
String t = domain.substring(i + 1);
h.put(t, h.getOrDefault(t, 0) + cnt);
}
}
}
List<String> r = new ArrayList<String>();
for (Map.Entry<String, Integer> entry: h.entrySet()) {
r.add(entry.getValue() + " " + entry.getKey());
}
return r;
}
}
public class Solution {
public IList<string> SubdomainVisits(string[] cpdomains) {
Dictionary<string, int> h = new Dictionary<string, int>();
foreach (string cpdomain in cpdomains) {
string[] tmp = cpdomain.Split(" ", 2);
int cnt = int.Parse(tmp[0]);
string domain = tmp[1];
Add(h, domain, cnt);
int m = domain.Length;
for (int i = 0; i < m; i++) {
if (domain[i] == '.') {
string t = domain.Substring(i + 1);
Add(h, t, cnt);
}
}
}
IList<string> r = new List<string>();
foreach (KeyValuePair<string, int> pair in h) {
r.Add(pair.Value + " " + pair.Key);
}
return r;
}
public void Add(Dictionary<string, int> h, string domain, int cnt) {
if (h.ContainsKey(domain) == false) {
h.Add(domain, cnt);
} else {
h[domain] += cnt;
}
}
}
typedef struct {
char* domain;
int cnt;
UT_hash_handle hh;
} HashItem;
void set(HashItem** h, char* domain, int cnt) {
HashItem* pEntry = NULL;
HASH_FIND_STR(*h, domain, pEntry);
if (pEntry == NULL) {
pEntry = malloc(sizeof(HashItem));
pEntry->domain = domain;
pEntry->cnt = cnt;
HASH_ADD_STR(*h, domain, pEntry);
} else {
pEntry->cnt += cnt;
}
}
char ** subdomainVisits(char ** cpdomains, int cpdomainsSize, int* returnSize){
HashItem* h = NULL;
for (int i = 0; i < cpdomainsSize; i++) {
char* token = strtok(cpdomains[i], " ");
int cnt = atoi(token);
char* domain = strtok(NULL, token);
set(&h, domain, cnt);
int m = strlen(domain);
for (int j = 0; j < m; j++) {
if (domain[j] == '.') {
set(&h, domain + j + 1, cnt);
}
}
}
*returnSize = HASH_COUNT(h);
char** r = malloc(sizeof(char*) * *returnSize);
int pos = 0;
HashItem* cur, *tmp;
HASH_ITER(hh, h, cur, tmp) {
char* t = malloc(sizeof(char) * (32 + strlen(cur->domain)));
sprintf(t, "%d %s", cur->cnt, cur->domain);
r[pos++] = t;
HASH_DEL(h, cur);
free(cur);
}
return r;
}
class Solution {
public:
vector<string> subdomainVisits(vector<string>& cpdomains) {
unordered_map<string, int> h;
for (string cpdomain : cpdomains) {
int spaceIndex = cpdomain.find(' ');
string tok = cpdomain.substr(0, spaceIndex);
int cnt = stoi(tok);
string domain = cpdomain.substr(spaceIndex + 1);
h[domain] += cnt;
int m = domain.size();
for (int i = 0; i < m; i++) {
if (domain[i] == '.') {
h[domain.substr(i + 1)] += cnt;
}
}
}
vector<string> r;
for (const auto& [key, value] : h) {
r.emplace_back(to_string(value) + " " + key);
}
return r;
}
};
class Solution: # dict 实现
def subdomainVisits(self, cpdomains: List[str]) -> List[str]:
h = dict()
for cpdomain in cpdomains:
cnt, domain = cpdomain.split(' ', 2)
h[domain] = h.get(domain, 0) + int(cnt)
for i, c in enumerate(domain):
if c == '.':
t = domain[i + 1:]
h[t] = h.get(t, 0) + int(cnt)
return [str(value) + ' ' + key for key, value in h.items()]
class Solution: # Counter 实现
def subdomainVisits(self, cpdomains: List[str]) -> List[str]:
h = Counter()
for cpdomain in cpdomains:
cnt, domain = cpdomain.split(' ', 2)
h[domain] += int(cnt)
for i, c in enumerate(domain):
if c == '.': h[domain[i + 1:]] += int(cnt)
return [str(value) + ' ' + key for key, value in h.items()]