• leetcode竞赛:20220904双周赛


    日期:20220903
    链接:https://leetcode.cn/contest/biweekly-contest-86/

    题目1

    class Solution {
    public:
        unordered_map mmap;
        bool findSubarrays(vector& nums) {
            int cur = nums[0] + nums[1];
            mmap[cur] = 1;
            int n = nums.size();
            for (int i = 2; i < n; i++) {
                cur -= nums[i - 2];
                cur += nums[i];
                if (mmap[cur] == 1) {
                    return true;
                }
                mmap[cur] = 1;
            }
            return false;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    简洁版补充

    class Solution {
    public:
        bool findSubarrays(vector& nums) {
            unordered_set sset;
            for (int i = 1; i < nums.size(); i++) {
                int s = nums[i] + nums[i - 1];
                if (sset.find(s) != sset.end()) {
                    return true;
                }
                sset.insert(s);
            }
            return false;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    题目2 6172. 严格回文的数字

    回文数判断

    class Solution {
    public:
        bool isStrictlyPalindromic(int n) {
            for (int i = 2; i <= n - 2; i++) {
                if (!check(n, i)) {
                    return false;
                }
            }
            return true;
        }
        bool check(int n, int b) {
            vector num;
            while (n) {
                num.push_back(n % b);
                n /= b;
            }
            for (int i = 0, j = num.size() - 1; i < j; i++, j--) {
                if (num[i] != num[j]) {
                    return false;
                }
            }
            return true;
    
        }
    };
    
    • 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

    可以证明结果都是false,可以举 n - 2 进制的反例:

    • n > 4 时,其n - 2进制表示为12,不可能是回文的,所以直接返回false
    class Solution {
    public:
        bool isStrictlyPalindromic(int n) {
            return false;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    题目3 6173. 被列覆盖的最多行数

    二进制枚举:枚举所有的覆盖情况

    class Solution {
    public:
        int maximumRows(vector>& mat, int cols) {
            int m = mat.size(), n = mat[0].size();
            int ret = 0;
            for (int i = 0; i < 1 << n; i++) {
                int x = 0, y = i;
                while (y) {
                    y = y & (y - 1);
                    x++;
                }
                if (x != cols) continue;
                int res = 0;
                for (int j = 0; j < m; j++) {
                    int flag = 1;
                    for (int k = 0; k < n; k++) {
                        if (mat[j][k] && !(i & (1 << k))) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) res++;
                }
                ret = max(ret, res);
            }
            return ret;
        }
    
    };
    
    • 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

    二进制枚举:枚举所有 覆盖 numSelect 列的情况

    枚举 0 , 1 , . . . , n − 1 {0,1, ...,n-1} 0,1,...,n1 所有大小为 k 的子集

    class Solution {
    public:
        int maximumRows(vector>& matrix, int numSelect) {
            int m = matrix.size(), n = matrix[0].size(), res = 0;
            int comb = (1 << numSelect) - 1;
            while (comb < 1 << n) {
                int cnt = 0;
                for (int i = 0; i < m; i++) {
                    int flag = 1;
                    for (int j = 0; j < n; j++) {
                        if (matrix[i][j] == 1 && !(comb & (1 << j)))  {
                            flag = 0;
                            break;
                        }
                    }
                    cnt += flag;
                }
                res = max(res, cnt);
                int x = comb & -comb, y = comb + x;
                comb = ((comb & ~y) / x >> 1) | y;
            }
            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

    深度优先搜索,暴力枚举所有的覆盖情况,二者运行速度是一样的。

    class Solution {
    public:
        int res;
        int retu;
        int maximumRows(vector>& mat, int cols) {
            res = 0;
            retu = 0;
            dfs(mat, 0, cols, 0);
            return retu;
        }
        void dfs(vector>& mat, int cur, int cols, int cl) {
            int n = mat[0].size();
            if (cur == cols) {
                calc(mat);
            }
            if (cl == n) return ;
            // 选cl列
            res |= (1 << cl);
            dfs(mat, cur + 1, cols, cl + 1);
            // 不选cl列
            res &= ~(1 << cl);
            dfs(mat, cur, cols, cl + 1);
        }
        void calc(vector>& mat) {
            int m = mat.size(), n = mat[0].size();
            int ret = 0;
            for (int i = 0; i < m; i++) {
                int flag = 1;
                for (int j = 0; j < n; j++) {
                    if (!(res & (1 << j)) && mat[i][j]) {
                        flag = 0;
                        break;
                    }
                }
                if (flag) ret++;
            }
            
            retu = max(retu, ret);
        }
    };
    
    • 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

    题目4 6143. 预算内的最多机器人数目

    这个比赛的时候看错题目了,题目要求是连续的。而且想到解法了,就是没写出来。虽然写出来也是错的。。。
    滑动窗口+单调队列做法:遍历一遍,查找左边的最大充电时间,用单减队列, O(n)复杂度
    滑动窗口维护区间和,如果超出限制,左窗口右移。顺便判断单调队列是否被移出。O(n)复杂度

    class Solution {
    public:
        typedef long long LL;
        int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
            int n = chargeTimes.size();
            deque que;
            LL sum = 0;
            int res = 0;
            for (int i = 0, j = 0; i < n; i++) {
                while (!que.empty() && chargeTimes[que.back()] <= chargeTimes[i]) que.pop_back();
                que.push_back(i);
                sum += runningCosts[i];
                while (!que.empty() && sum * (i - j + 1) + chargeTimes[que.front()] > budget) {
                    sum -= runningCosts[j];
                    if (que.front() == j) que.pop_front();
                    j++;
                }
                res = max(res, i - j + 1);
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    如果是任意选取的,那么得用二分答案来做。O(log(n)) * O(nlog(n))。
    第一个log(n)用来二分答案。后面的O(nlog(n))用来判断答案是否正确:以下代码不保证正确

    typedef long long LL;
    typedef pair PLL;
    class Solution {
    public:
        int maximumRobots(vector& x, vector& y, long long m) {
            int n = x.size();
            vector ms;
            for (int i = 0; i < n; i++) {
                ms.push_back({x[i], y[i]});
            }
            sort(ms.begin(), ms.end());
            int l = 0, r = n - 1;
            while (l < r) {
                int mid = (l + r + 1) / 2;
                if (check(ms, mid, m)) {
                    l = mid;
                } else {
                    r = mid - 1;
                }
            }
            return l;
        }
        bool check(vector &ms, int k, int m) {
            int n = ms.size();
            LL sum = 0;
            priority_queue heap;
            for (int i = 0; i < n; i++) {
                if (heap.size() < k) {
                    sum += ms[i].second;
                    heap.push(ms[i].second);
                }
                if (heap.size() < k) continue;
    
                if (heap.top() > ms[i].second) {
                    sum -= heap.top();
                    heap.pop();
                    heap.push(ms[i].second);
                    sum += ms[i].second;
                }
    
                if (sum * k + ms[i].first < m) {
                    return true;
                }
    
            }
            return false;
        }
    };
    
    • 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
  • 相关阅读:
    javabasic
    CST--如何在PCB三维模型中自由创建离散端口
    中国钛合金自行车出口海外营销策略-大舍传媒
    导轨式安装压力应变桥信号处理差分信号输入转换变送器0-10mV/0-20mV/0-±10mV/0-±20mV转0-5V/0-10V/4-20mA
    文本的换行与包裹 之 简介
    虚拟机安装zookeeper集群
    Android Startup启动优化
    [PyTorch][chapter 53][Auto Encoder 实战]
    Vue3+nodejs全栈项目(资金管理系统)——前端篇
    linux中qt编写串口程序,linux下基于QT的串口程序
  • 原文地址:https://blog.csdn.net/weixin_43233774/article/details/126684648