• leetcode竞赛:20220911周赛


    日期:20220911
    链接:https://leetcode.cn/contest/weekly-contest-310/

    题目一:6176. 出现最频繁的偶数元素

    次数相等时选最小的数。因为这个WA一次

    class Solution {
    public:
        int mostFrequentEven(vector& nums) {
            unordered_map ct;
            int ret = -1, m = 0;
            for (auto c: nums) {
                if (c % 2) continue;
                ct[c]++;
                if (ct[c] > m) {
                    m = ct[c];
                    ret = c;
                } else if (ct[c] == m && c < ret) {
                    ret = c;
                }
            }
            return ret;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    题目二: 6177. 子字符串的最优划分

    直接贪心就行。

    class Solution {
    public:
        int partitionString(string s) {
            unordered_map dict;
            int cnt = 0;
            for (int i = 0, j = 0; i <= s.size(); i++) {
                char c = s[i];
                if (dict[c] > 0) {
                    cnt++;
                    dict.clear();
                }
                dict[c]++;
            }
            return cnt + 1;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    看到一个大神的答案。可以用bitset来做。
    第二次写,双指针更熟练了。

    class Solution {
    public:
        int partitionString(string s) {
            int n = s.size(), cnt = 0;
            vector wd(26);
            for (int i = 0, j = 0; i < n; i = j) {
                while (j < n && wd[s[j] - 'a'] == 0) {
                    wd[s[j++] - 'a']++;
                }
                cnt++;
                for (int i = 0; i < 26; i++) wd[i] = 0;
            }
            return cnt;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    题目三: 6178. 将区间分为最少组数

    这题,没做出来。。。很郁闷。想着是贪心,按顺序排序后,一遍一遍的尽可能多的把所有不重叠的区间选完。
    但是33个样例,是重复的得用multiset的过。换成multiset后,34个又不过。
    看答案是用区间覆盖来做。某个区间最多被覆盖多少次,就需要分多少组。所以通过差分数组,可以统计每一个区间中的数字被覆盖了多少次。

    class Solution {
    public:
        int minGroups(vector>& intervals) {
            int n = intervals.size();
            vector diff(1000005);
            for (auto &vc : intervals) {
                diff[vc[0]]++;
                diff[vc[1] + 1]--;
            }
            int res = diff.front();
            for (int i = 1; i <= 1000000; i++) {
                diff[i] += diff[i - 1];
                res = max(res, diff[i]);
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    第二次实现,开始还是超时了。快速敏锐的想到用 multiset 来做,然后通过了。还是第一种差分的方式好,但是难想。
    事实上,完全可以用优先队列来做,因为优先队列也允许重复。

    class Solution {
    public:
        int minGroups(vector>& intervals) {
            int n = intervals.size(), cnt = 0;
            sort(intervals.begin(), intervals.end());
            multiset sset;
            for (auto &p : intervals) {
                if (sset.empty() || *sset.begin() >= p[0]) {
                    sset.insert(p[1]);
                } else {
                    int x = *sset.begin();
                    sset.erase(sset.begin());
                    sset.insert(p[1]);
                }
            }
    
            return sset.size();
        }
    };
    // 优先队列版
    class Solution {
    public:
        int minGroups(vector>& intervals) {
            int n = intervals.size(), cnt = 0;
            sort(intervals.begin(), intervals.end());
            priority_queue, greater> que;
            for (auto &p : intervals) {
                if (que.empty() || que.top() >= p[0]) {
                    que.push(p[1]);
                } else {
                    int x = que.top();
                    que.pop();
                    que.push(p[1]);
                }
            }
    
            return que.size();
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    这里开了一个100w大小的数组,MB级别的。

    题目四:6206. 最长递增子序列 II

    典型的动态规划。 f ( i ) f(i) f(i) 表示,以索引 i i i 结尾的子序列,最长是多少。对于 f ( i ) f(i) f(i) ,我们要找到 j j j,满足 j < i j < i j<i,并且
    n u m s [ i ] − k ≤ n u m s [ j ] < n u m s [ i ] nums[i] - k \le nums[j] < nums[i] nums[i]knums[j]<nums[i]
    的最大的 f [ j ] f[j] f[j]。如果这样做,每次转移需要遍历 [ 0 , i ) [0, i) [0,i) 就是 O ( n 2 ) O(n^2) O(n2) 的复杂度,肯定过不了。
    可以转化思维:找索引 j j j 我求不了,干脆我直接求 n u m s [ j ] nums[j] nums[j] 值得范围得了。直接找 [ n u m s [ i ] − k , n u m s [ i ] − 1 ] [nums[i] - k, nums[i] - 1] [nums[i]k,nums[i]1] 这个区间的最大值。反正 nums[i] 的范围只有 10w。线段树搞定。
    最近整理了线段树模板:

    class SegmentTree {
    public:
        void init() {
            _build_tree(1, 0, _n);
        }
        SegmentTree(int n) : _n(n), tree((n + 2) << 2) { }
    
        void modify(int idx, int val) {
            _modify(1, 0, _n, idx, val);
        }
        int query(int L, int R) {
            return _query(1, 0, _n, L, R);
        }
    private:
        void _build_tree(int root, int L, int R) {
            if (L == R) {
                // tree[root].max_num = arr[l];
                return;
            }
            int mid = (L + R) >> 1;
            _build_tree(root * 2, L, mid);
            _build_tree(root * 2 + 1, mid + 1, R);
            _update(root);
            return ;
        }
        void _modify(int root, int rl, int rr, int idx, int val) {
            if (rl == rr) {
                tree[root] = val;
                return;
            }
            int mid = (rl + rr) >> 1;
            if (idx <= mid) {
                _modify(root << 1, rl, mid, idx, val);
            } else {
                _modify(root << 1 | 1, mid + 1, rr, idx, val);
            }
            _update(root);
            return ;
        }
    
        int _query(int root, int rl, int rr, int L, int R) {
    
            if (rl >= L && rr <= R) {
                return tree[root];
            }
            int ans = INT_MIN;
            int mid = (rl + rr) >> 1;
            if (mid >= L) {
                ans = max(ans, _query(root << 1, rl, mid, L, R));
            }
            if (mid < R) {
                ans = max(ans, _query(root << 1 | 1, mid + 1, rr, L, R));
            }
            return ans;
        }
        void _update(int root) {
            tree[root] = max(tree[root << 1], tree[root << 1 | 1]);
            return;
        }
        // default [0, n] root is 1;
        int _n;
        vector tree;
    };
    
    class Solution {
    public:
        int lengthOfLIS(vector& nums, int k) {
            int n = nums.size();
            vector f(n);
            int res = 1;
            SegmentTree sg(100000);
            sg.init();
            for (int i = 0; i < n; i++) {
                int l = max(0, nums[i] - k), r = nums[i] - 1;
                f[i] = sg.query(l, r) + 1;
                sg.modify(nums[i], f[i]);
                res = max(res, f[i]);
            }
            return res;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
  • 相关阅读:
    CANoe-以太网Link up问题、如何打开TC8参数配置文件
    OpenCV项目实战-深度学习去阴影-图像去阴影
    9、Redis与SpringBoot整合
    【Redis】Redis 的基础数据结构 以及 各种数据结构常用命令使用示例
    centos7 firewalld ip转发设置、安装docker-compose出现错误、docker-compose部署Yapi
    交付实施工程师是做什么的?
    计算机网络的OSI七层模型
    天翼云乘风新基建,构建数字化转型“4+2”能力体系
    VMware ESXi 8.0U2c macOS Unlocker & OEM BIOS ConnectX-3 网卡定制版 (集成驱动版)
    Linux学习——标准IO的读写
  • 原文地址:https://blog.csdn.net/weixin_43233774/article/details/126805066