Leetcode第324场周赛题解

第一题

题目链接

6265. 统计相似字符串对的数目

题解

用set比较即可。

class Solution {
public:
    int similarPairs(vector<string>& words) {
        vector<set<char>> a(words.size());
        int ans = 0;
        for (int i = 0; i < words.size(); i++) {
            set<char> b(begin(words[i]),end(words[i]));
            a[i] = b;
            for (int j = 0; j < i; j++) {
                if (a[j] == b) ans++;
            }
        }
        return ans;
    }
};

复杂度分析

时间复杂度为 O ( n 2 ) O(n^2) O(n2),其中n为words的长度。

第二题

题目链接

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

题解

不断循环,找出全部质因数求和,直到质因数和与原数相同,即为所求最小值。

class Solution {
public:
    int find(int n) {
        int ans = 0;
        int t = n;
        for (int i = 2; i <= n; i++) {
            while(t % i == 0) {
                t /= i;
                ans += i;
            }
            if (t == 1) break;
        }
        return ans;
    }
    int smallestValue(int n) {
        int ans = n;
        while(1) {
            ans = find(n);
            if (ans == n) break;
            n = ans;
        }
        return ans;
    }
};

复杂度分析

时间复杂度为 O ( n ) O(\sqrt{n}) O(n )

第三题

题目链接

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

题解

这道题分析清楚情况很简单。
我是用map存储了两个顶点是否存在,当然也可以用set存储某条边是否存在。
根据所有节点度数之和必为偶数,我们可以得知必不存在奇数个度数为奇数的节点。
根据最多添加两条边,且无自环重边的要求,我们可知:

  • 当度数为奇数的节点(下简称奇节点)个数大于4时,无论如何都无法找到两条边使所有节点度数为偶数。
  • 当奇节点个数为0时,我们直接返回true。
  • 那么我们只需要讨论奇节点个数为2和为4的情况。
    • 当奇节点个数为2时,如果存在一个节点度数为0,或存在一个节点与这两个奇节点之间都没有边,或两个节点之间没有边,则返回true;否则返回false。
    • 当奇节点个数为4时,我们只需判断这四个节点能否分成两组,每组中的两个点之间都不存在边。如果可以就返回true,否则返回false。
class Solution {
public:
    bool isPossible(int n, vector<vector<int>>& edges) {
        map<int,map<int,int>> a;
        map<int,vector<int>> m;
        for (int i = 0; i < edges.size(); i++) {
            m[edges[i][0]].push_back(edges[i][1]);
            m[edges[i][1]].push_back(edges[i][0]);
            a[edges[i][0]][edges[i][1]] = 1;
            a[edges[i][1]][edges[i][0]] = 1;
            if (m[edges[i][0]].size() == n - 1 && n % 2 == 0) return false;
            if (m[edges[i][1]].size() == n - 1 && n % 2 == 0) return false;
        }
        map<int,vector<int>> d;
        for (int i = 1; i <= n; i++) {
            if (m.count(i)) {
                d[m[i].size()%2 + 1].push_back(i);
            } else {
                d[0].push_back(i);
            }
        }
        if (d.count(2)&&d[2].size()>4) return false;
        if (d.count(2) == 0) return true;
        if (d[2].size() == 2) {
            if (d.count(0)) return true;
            if (a[d[2][0]][d[2][1]] == 0) return true;
            for (int i = 0; i < d[1].size(); i++) {
                if (a[d[2][0]][d[1][i]] == 0 && a[d[2][1]][d[1][i]] == 0) return true;
            }
        } else if (d[2].size() == 4) {
            if (a[d[2][0]][d[2][1]]==0 && a[d[2][2]][d[2][3]]==0) return true;
            if (a[d[2][0]][d[2][2]]==0 && a[d[2][1]][d[2][3]]==0) return true;
            if (a[d[2][0]][d[2][3]]==0 && a[d[2][1]][d[2][2]]==0) return true;
        }
        return false;
    }
};

复杂度分析

时间复杂度为 O ( m + n ) O(m+n) O(m+n),其中m为edges的长度。

第四题

题目链接

6268. 查询树中环的长度

题解

这道题可以先分别计算两个点到根节点的距离,求和得到a,然后求出两个点最近的父节点到根节点的距离b,易证题目所求即为a-2*b+1。

class Solution {
public:
    int find(long long n) {
        int ans = 0;
        while(n != 1) {
            n /= 2;
            ans++;
        }
        return ans;
    }
    vector<int> cycleLengthQueries(int n, vector<vector<int>>& q) {
        vector<int> ans(q.size());
        for (int i = 0; i < q.size(); i++) {
            int left = find(q[i][0]);
            int right = find(q[i][1]);
            int flag = 1;
            while(q[i][0] != 1 && q[i][1] != 1) {
                if (q[i][0] > q[i][1]) q[i][0] /= 2;
                else if (q[i][1] > q[i][0]) q[i][1] /= 2;
                else {
                    flag = q[i][1];
                    break;
                }
            }
            if (flag == 1) ans[i] = left + right + 1;
            else {
                int d = find(flag);
                ans[i] = left + right + 1 - 2 * d;
            }
        }
        return ans;
    }
};

复杂度分析

时间复杂度为 O ( n m ) O(nm) O(nm),其中m为q的长度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值