• leetcode竞赛:20220828周赛


    日期:20220828
    链接:https://leetcode.cn/contest/weekly-contest-308/
    leetcode算法周赛,简要记录。

    第一题 6160. 和有限的最长子序列

    这道题应该和第二题换一下位置。感觉这道题比第二题难一些。不过后来知道这个题数据量小,不用前缀和+二分也能做。
    但是能证明:排序后从最小的数开始算,就是最后答案,还是有些思维量的。

    // 补充 非二分的包子做法
    class Solution {
    public:
        vector answerQueries(vector& nums, vector& queries) {
            sort(nums.begin(), nums.end());
            for (int i = 1; i < nums.size(); i++) nums[i] += nums[i - 1];
            vector res;
            for (auto x:queries) {
                int i = 0;
                for (; i < nums.size(); i++) {
                    if (nums[i] > x) break;
                }
                res.push_back(i);
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    class Solution {
    public:
        vector answerQueries(vector& nums, vector& queries) {
            vector sums;
            sort(nums.begin(), nums.end());
            sums.push_back(0);
            for (auto c : nums) {
                sums.push_back(sums.back() + c);
            }
            vector ans;
            for (int k : queries) {
                int l = 0, r = sums.size() - 1;
                while (l < r) {
                    int mid = (l + r + 1) / 2;
                    if (sums[mid] <= k) {
                        l = mid;
                    } else {
                        r = mid - 1;
                    }
                }
                ans.push_back(l);
                
            }
            return ans;
            
        }
    };
    
    • 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

    第二题 6161. 从字符串中移除星号

    按照题意模拟就行,非常简单

    class Solution {
    public:
        string removeStars(string s) {
            string k;
            for (auto c : s) {
                if (c == '*') k.pop_back();
                else k += c;
                
            }
            return k;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    第三题 6162. 收集垃圾的最少总时间

    题目很长,很唬人。实际上,只要三个车是独立的,可以直接计算。题目比较简单,但是里面涉及的值比较多。比赛时,没捋清楚这些值,编码复杂了一些,甚至都用了后缀和…。以后注意一些,想清楚数据之后,再编码.

    typedef long long LL;
    class Solution {
    public:
        int garbageCollection(vector& garbage, vector& travel) {
            int n = garbage.size();
            vector mm(n + 1, 0), gg(n + 1, 0), pp(n + 1, 0);
            
            for (int i = n - 1; i >= 0; i--) {
                LL a = 0, b = 0, c = 0;
                cacl(garbage[i], a, b, c);
                mm[i] = mm[i + 1] + a;
                pp[i] = pp[i + 1] + b;
                gg[i] = gg[i + 1] + c;
            }
            int res = 0;
            for (int i = 0; i < n; i++) {
                if (mm[i]) {
                    res += mm[i] - mm[i + 1];
                    if (mm[i + 1])  res += travel[i];
                }
                if (gg[i]) {
                    res += gg[i] - gg[i + 1];
                    if (gg[i + 1])  res += travel[i];
                }
                if (pp[i]) {
                    res += pp[i] - pp[i + 1];
                    if (pp[i + 1])  res += travel[i];
                }
            }
            return res;
        }
        void cacl(string &s, LL &a, LL &b, LL &c) {
            for (auto t : s) { // auto 写成了c,还debug了好久
                if (t == 'M') a++;
                if (t == 'P') b++;
                if (t == 'G') c++;
            }
        }
    };
    
    
    • 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

    第二次编码,要简洁的多

    class Solution {
    public:
        int garbageCollection(vector& garbage, vector& travel) {
            int res = cacl(garbage, travel, 'G');
            res += cacl(garbage, travel, 'P');
            res += cacl(garbage, travel, 'M');
            return res;
        }
        int cacl(vector& garbage, vector& travel, char c) {
            int n = garbage.size(), res = 0;
            for (int i = 0, last = 0; i < n; i++) {
                for (auto cc : garbage[i]) {
                    if (cc == c) {
                        while (last != i) res += travel[last++];
                        res++;
                    }
                }
            }
            cout << res << endl;
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    第四题 6163. 给定条件下构造矩阵

    只要想到拓扑排序,并且想到行与列相互独立,就可以做。
    比赛用了dfs的拓扑排序算法,需要两个全局值,来判断环和存储答案。用入度计算来拓扑排序更好一些。

    class Solution {
    public:
        vector sorted;
        int flag;
        vector> buildMatrix(int k, vector>& rowConditions, vector>& colConditions) {
            vector> g1(k + 1), g2(k + 1);
            for (auto pp : rowConditions) {
                g1[pp[1]].push_back(pp[0]);
            }
            for (auto pp : colConditions) {
                g2[pp[1]].push_back(pp[0]);
            }
            vector> res;
            
            flag = 0;
            vector visited(k + 1);
            for (int i = 1; i <= k; i++) {
                if (!visited[i]) {
                    dfs(g1, i, visited);    
                }
            }
            if (flag) return res;
            
            vector sorted2 = sorted;
            sorted.clear();
            for (auto& c : visited) c = 0;
            for (int i = 1; i <= k; i++) {
                if (!visited[i]) {
                    dfs(g2, i, visited);    
                }
            }
            if (flag) return res;
            
            // 两个循环来建图。实际上可以一个循环来做,但是分开更容易想
            unordered_map idx;
            for (int i = 1; i <= k; i++) {
                vector t(k); 
                t[0] = sorted2[i - 1];  // 把行的拓扑序放在每一行的开始,并记录该数字在第几行。
                idx[t[0]] = i - 1;
                res.push_back(t);
            }
            for (int i = 1; i <= k; i++) {
                int nm = sorted[i - 1];  // 表示数字nm要在第 i 列
                swap(res[idx[nm]][0], res[idx[nm]][i - 1]); // 找到nm的行数。交换首值和第i列的值
            }
            
            return res;
        }
        void dfs(const vector> &g, int i, vector &visited) {
            visited[i] = 1;
            for (int t : g[i]) {
                if (visited[t] == 1) {
                    flag = 1;
                    return;
                } else if (!visited[t]) {
                    dfs(g, t, visited);
                }
            }
            visited[i] = 2;
            sorted.push_back(i);
        }
        
    };
    
    
    • 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

    链式前向星

    int h[405], e[10005], nx[10005], idx, rd[405], st[405];
    class Solution {
    public:
        void add(int a, int b) {
            e[idx] = b, rd[b]++, nx[idx] = h[a], h[a] = idx++;
        }
        vector Topology(int k) {
            memset(st, 0, sizeof st);
            vector res;
            for (int i = 1; i <= k; i++) {
                int v = -1;
                for (int i = 1; i <= k; i++) if (st[i] == 0 && rd[i] == 0) {
                    v = i;
                    break;
                }
                res.push_back(v);
                
                if (v == -1) break;
                st[v] = 1;
                for (int j = h[v]; ~j; j = nx[j]) {
                    int nv = e[j];
                    rd[nv]--;
                }
            }
            return res;
        }
        vector> buildMatrix(int k, vector>& rowConditions, vector>& colConditions) {
            // 基于行拓扑排序
            memset(h, -1, sizeof(h));
            memset(rd, 0, sizeof(rd));
            idx = 0;
            for (auto &p : rowConditions) {
                int a = p[0], b = p[1];
                add(a, b);
            }
            vector rows = Topology(k);
            if (rows.size() != k) return {};
            vector mmap(k + 1);
            // 建立行索引映射
            for (int i = 0; i < k; i++) {
                mmap[rows[i]] = i;
            }
            // 基于列拓扑排序
            memset(h, -1, sizeof(h));
            memset(rd, 0, sizeof(rd));
            idx = 0;
            for (auto &p : colConditions) {
                int a = p[0], b = p[1];
                add(a, b);
            }
    
            vector cols = Topology(k);
            if (cols.size() != k) return {};
    
            // 构造结果
            vector> res(k, vector(k));
            for (int i = 0; i < k; i++) {
                res[mmap[cols[i]]][i] = cols[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
  • 相关阅读:
    30岁之前什么新技术我都学,30岁之后什么新技术我都不学。
    面试总结-单例模式之Java实现
    【Docker 基础教程】Mysql主从服务搭建------Mysql容器闪退及容器名冲突系列问题
    C语言 找出数组中最大的数(输入10个数)
    AD学习笔记
    02_diffusion_models_from_scratch_CN
    MySQL之从单机到集群
    Jtti:如何设置CentOS系统以防止恶意代码的自动执行
    如何识别假爬虫?
    Chaos Vantage最低配置要求,需要什么显卡
  • 原文地址:https://blog.csdn.net/weixin_43233774/article/details/126573440