用哈希映射数据结构,分割字符串为数组,截取字符串,求解《811. 子域名访问计数》

2022-10-05 05:58:31
用哈希映射数据结构,用 split / explode /  stirngs.Split / strtok 分割字符串为数组,substring / substr / 指针截取字符串,求解《811. 子域名访问计数》

例题

811. 子域名访问计数

网站域名 "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()]

分类讨论 + 顺序遍历,固定列表 / 哈希映射 + 滑动窗口,3 解法求解《904. 水果成篮》
分类讨论 + 顺序遍历,固定列表 / 哈希映射 + 滑动窗口,3 解法求解《904. 水果成篮》
顺序遍历,哈希集合,求解《817. 链表组件》
顺序遍历,哈希集合,求解《817. 链表组件》
顺序遍历,求解《1790. 仅执行一次字符串交换能否使两个字符串相等》
顺序遍历,求解《1790. 仅执行一次字符串交换能否使两个字符串相等》