Skip to content

第 324 场周赛

比赛链接

Date: 2022-12-18

A 统计相似字符串对的数目

class Solution {
public:
    int similarPairs(vector<string>& s) {
        int res = 0;
        unordered_map<int, int> mp;
        for (auto t : s) {
            int mask = 0;
            for (auto c : t) {
                mask |= 1 << (c - 'a');
            }
            mp[mask]++;
        }
        for (auto &[k, v] : mp) {
            res += v * (v - 1) / 2;
        }
        return res;
    }
};
1
2
3
4
class Solution:
    def similarPairs(self, words: List[str]) -> int:
        cnt = collections.Counter(map(lambda x: ''.join(sorted(list(set(x)))), words))
        return sum(cnt[key] * (cnt[key] - 1) // 2 for key in cnt)

复杂度分析

  • 时间复杂度:\(O(nm)\)
  • 空间复杂度:\(O(n)\)

B 使用质因数之和替换后可以取到的最小值

质因数分解

class Solution {
public:
    int smallestValue(int n) {
        auto get = [&](int n) {
            int sum = 0;
            for (int i = 2; i * i <= n; i++) {
                if (n % i) continue;
                while (n % i == 0) {
                    n /= i;
                    sum += i;
                }
            }
            if (n > 1) sum += n;
            return sum;
        };
        while (true) {
            int m = get(n);
            if (m == n) break;
            n = m;
        }
        return n;
    }
};

复杂度分析

  • 时间复杂度:\(O(\sqrt n)\)
  • 空间复杂度:\(O(1)\)

C 添加边使所有节点度数都为偶数

对于度数为 2 的特殊处理即可。

class Solution {
public:
    bool isPossible(int n, vector<vector<int>>& edges) {
        vector<vector<int>> g(n + 1);
        for (auto &v : edges) {
            g[v[0]].push_back(v[1]);
            g[v[1]].push_back(v[0]);
        }
        for (int i = 1; i <= n; i++) {
            sort(g[i].begin(), g[i].end());
        }
        int odd = 0;
        vector<int> cand;
        for (int i = 1; i <= n; i++) {
            if (g[i].size() & 1) {
                odd++;
                cand.push_back(i);;
            }
        }
        if (odd != 0 && odd != 2 && odd != 4) {
            return false;
        }
        if (odd == 0) return true;

        auto get = [&](int x, int y) {
            int pos = lower_bound(g[x].begin(), g[x].end(), y) - g[x].begin();
            if (pos < g[x].size() && g[x][pos] == y) {
                return false;
            }
            return true;
        };
        if (odd == 2) {
            if (get(cand[0], cand[1])) {
                return true;
            }
            for (int i = 1; i <= n; i++) {
                if (i != cand[0] && i != cand[1]) {
                    if (get(cand[0], i) && get(cand[1], i)) {
                        return true;
                    }
                }
            }
            return false;
        }

        return (get(cand[0], cand[1]) && get(cand[2], cand[3])) || (get(cand[0], cand[2]) && get(cand[1], cand[3])) || (get(cand[0], cand[3]) && get(cand[1], cand[2]));
    }
};

复杂度分析

  • 时间复杂度:\(O(n\log n)\)
  • 空间复杂度:\(O(m)\)

D 查询树中环的长度

两个点的编号,二进制表示中最长相同前缀即最近公共祖先,剩下的部分就是距离

class Solution {
public:
    vector<int> cycleLengthQueries(int n, vector<vector<int>>& queries) {
        vector<int> res;
        for (auto &v : queries) {
            int x = v[0], y = v[1];
            int ret = 0;
            while (x != y) {
                x > y ? x /= 2 : y /= 2;
                ret++;
            }
            res.push_back(ret + 1);
        }
        return res;
    }
};

复杂度分析

  • 时间复杂度:\(O(n\log n)\)
  • 空间复杂度:\(O(1)\)
本文访问