第 380 场 LeetCode 周赛题解

A 最大频率元素计数

模拟:先统计元素的频率,然后求由最大频率的元素的总频率

cpp 复制代码
class Solution {
public:
    int maxFrequencyElements(vector<int> &nums) {
        unordered_map<int, int> cnt;
        for (auto x: nums)
            cnt[x]++;
        int mx = 0, s = 0;
        for (auto [_, f]: cnt)
            if (f > mx) {
                mx = f;
                s = f;
            } else if (f == mx)
                s += f;
        return s;
    }
};

B 找出数组中的美丽下标 I

同t4...

cpp 复制代码
class Solution {
public:
    vector<int> beautifulIndices(string s, string a, string b, int k) {
        srand(time(0));//随机种子
        int e = 2333 + rand() % 100, mod = 1e9 + rand() % 100;
        shash hs(s, e, mod), ha(a, e, mod), hb(b, e, mod);
        vector<int> vi, vj;
        int ns = s.size(), na = a.size(), nb = b.size();
        for (int i = 0; i <= ns - na; i++)
            if (hs(i, i + na - 1) == ha(0, na - 1))
                vi.push_back(i);
        for (int j = 0; j <= ns - nb; j++)
            if (hs(j, j + nb - 1) == hb(0, nb - 1))
                vj.push_back(j);
        vector<int> res;
        for (auto i: vi) {
            auto l = lower_bound(vj.begin(), vj.end(), i - k);
            auto r = lower_bound(vj.begin(), vj.end(), i + k + 1);
            if (l != r)
                res.push_back(i);
        }
        return res;
    }

    class shash {//字符串哈希模板
    public:
        using ll = long long;
        vector<ll> pres;
        vector<ll> epow;
        ll e, p;

        shash(string &s, ll e, ll p) {
            int n = s.size();
            this->e = e;
            this->p = p;
            pres = vector<ll>(n + 1);
            epow = vector<ll>(n + 1);
            epow[0] = 1;
            for (int i = 0; i < n; i++) {
                pres[i + 1] = (pres[i] * e + s[i]) % p;
                epow[i + 1] = (epow[i] * e) % p;
            }
        }

        ll operator()(int l, int r) {
            ll res = (pres[r + 1] - pres[l] * epow[r - l + 1] % p) % p;
            return (res + p) % p;
        }
    };
};

C 价值和小于等于 K 的最大数字

二分 + 数学:通过二分枚举答案,这需要求不超过 m i d mid mid 的非负数( 0 0 0 的价值和为 0 0 0 不影响答案)的价值和,枚举二进制中的满足 i % x = = 0 i \% x == 0 i%x==0 的第 i i i 位, 0 ∼ m i d 0\sim mid 0∼mid 的第 i i i 位形成长为 2 i 2^i 2i 的循环数列的前 m i d + 1 mid+1 mid+1 项: 0 , ⋯   , 0 ⏟ 2 i − 1 个 0 , 1 , ⋯   , 1 ⏟ 2 i − 1 个 1 ⋯ \underset{2^{i-1}个0}{\underbrace{0,\cdots,0} } ,\underset{2^{i-1}个1}{\underbrace{1,\cdots,1} } \cdots 2i−1个0 0,⋯,0,2i−1个1 1,⋯,1⋯,所以可以直接求 0 ∼ m i d 0\sim mid 0∼mid 中第 i i i 位为 1 1 1 的数的数目

cpp 复制代码
class Solution {
public:
    using ll = long long;

    long long findMaximumNumber(long long k, int x) {
        ll l = 1, r = 1e15;
        while (l < r) {
            ll mid = (l + r + 1) / 2;
            ll s = 0;
            for (int i = 0; i < 50; i++)
                if ((i + 1) % x == 0) {
                    ll e = 1LL << (i + 1), se = 1LL << i;
                    ll c = (mid + 1) / e, mod = (mid + 1) % e;
                    s += c * se + (mod > se ? mod - se : 0);
                }
            if (s <= k)
                l = mid;
            else
                r = mid - 1;
        }
        return l;
    }
};

D 找出数组中的美丽下标 II

字符串哈希 + 二分:先用字符串哈希求出满足 0 ≤ i ≤ s . l e n g t h − a . l e n g t h 0 \le i \le s.length - a.length 0≤i≤s.length−a.length 和 s [ i , ( i + a . l e n g t h − 1 ) ] = a s[i,(i + a.length - 1)]=a s[i,(i+a.length−1)]=a 的 i i i 构成的有序数组 v i vi vi,和满足 0 ≤ j ≤ s . l e n g t h − b . l e n g t h 0 \le j \le s.length - b.length 0≤j≤s.length−b.length 和 s [ j , ( j + b . l e n g t h − 1 ) ] = b s[j,(j + b.length - 1)]=b s[j,(j+b.length−1)]=b 的 j j j 构成的有序数组 v j vj vj ,然后枚举 v i vi vi 中的 i i i ,在 v j vj vj 中二分查找 j ∈ [ i − k , i + k − 1 ) j\in [i-k,i+k-1) j∈[i−k,i+k−1) ,如果存在这样的 j j j ,则将 i i i 加入答案数组

cpp 复制代码
class Solution {
public:
    vector<int> beautifulIndices(string s, string a, string b, int k) {
        srand(time(0));//随机种子
        int e = 2333 + rand() % 100, mod = 1e9 + rand() % 100;
        shash hs(s, e, mod), ha(a, e, mod), hb(b, e, mod);
        vector<int> vi, vj;
        int ns = s.size(), na = a.size(), nb = b.size();
        for (int i = 0; i <= ns - na; i++)
            if (hs(i, i + na - 1) == ha(0, na - 1))
                vi.push_back(i);
        for (int j = 0; j <= ns - nb; j++)
            if (hs(j, j + nb - 1) == hb(0, nb - 1))
                vj.push_back(j);
        vector<int> res;
        for (auto i: vi) {
            auto l = lower_bound(vj.begin(), vj.end(), i - k);
            auto r = lower_bound(vj.begin(), vj.end(), i + k + 1);
            if (l != r)
                res.push_back(i);
        }
        return res;
    }

    class shash {//字符串哈希模板
    public:
        using ll = long long;
        vector<ll> pres;
        vector<ll> epow;
        ll e, p;

        shash(string &s, ll e, ll p) {
            int n = s.size();
            this->e = e;
            this->p = p;
            pres = vector<ll>(n + 1);
            epow = vector<ll>(n + 1);
            epow[0] = 1;
            for (int i = 0; i < n; i++) {
                pres[i + 1] = (pres[i] * e + s[i]) % p;
                epow[i + 1] = (epow[i] * e) % p;
            }
        }

        ll operator()(int l, int r) {
            ll res = (pres[r + 1] - pres[l] * epow[r - l + 1] % p) % p;
            return (res + p) % p;
        }
    };
};
相关推荐
_WndProc8 分钟前
C++ 日志输出
开发语言·c++·算法
努力学习编程的伍大侠21 分钟前
基础排序算法
数据结构·c++·算法
XiaoLeisj1 小时前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin2 小时前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿2 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd2 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript