• 第308场周赛 INnoVation


    这次差两分钟做出最后一道题

    第308场周赛

    2389. 和有限的最长子序列

    我用的双重循环,时间复杂度挺高的,但是蛮有意思的哈哈哈

    class Solution {
    public:
        vector<int> answerQueries(vector<int>& nums, vector<int>& query) {
            vector<int> ans;
            sort(nums.begin(), nums.end());
            for(auto val : query){
                int st = 0, sum = 0, res = 0;
                for(int i = 0; i < nums.size(); i++){
                    sum += nums[i];
                    while(sum > val){
                        sum -= nums[st];
                        ++st;
                    }
                    res = max(res, i - st + 1);
                }
                ans.push_back(res);
            }
            return ans;
        }
    };
    

    (贪心,前缀和,二分) \(O((n+m)logn)\)

    • 显然选择的数字越小最终的子集和也就会尽可能小。

    • 可以先把 nums 数组从小到大排序,然后对于每个询问 qq,二分查找第一个大于 qq 的前缀和位置 pp 作为答案。

    时间复杂度

    • 排序的时间复杂度为 O(nlogn)。
    • 排序后,每个询问二分的时间复杂度为 O(logn)。
    • 故总时间复杂度为 O((n+m)logn)。

    空间复杂度

    需要 O(m+logn)的额外空间存储答案以及排序的递归系统栈。

    class Solution {
    public:
        vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
            const int n = nums.size();
    
            sort(nums.begin(), nums.end());
    
            for (int i = 1; i < n; i++)
                nums[i] += nums[i - 1];
    
            vector<int> ans;
    
            for (int q : queries)
                ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());
    
            return ans;
        }
    };
    

    2390. 从字符串中移除星号

    使用栈进行模拟,遇到*出栈,其他的进栈

    时间复杂度

    字符串扫描一遍,时间复杂度\(O(N)\)

    空间复杂度

    需要额外的和s一样长的空间,时间复杂度是\(O(N)\)

    代码

    const int N = 1e5 + 10;
    char s[N];
    class Solution {
    public:
        string removeStars(string str) {
            int top = -1;
            for(char &c : str){
                if(c == '*') --top;
                else s[++top] = c;
            }
            string ans = "";
            for(int i = 0; i <= top; i++)
                ans += s[i];
            return ans;
        }
    };
    

    2391. 收集垃圾的最少总时间

    (模拟) O(nL)

    1. 答案可以拆分成所有房子的垃圾数量总和,再加上每辆垃圾车行驶到的最后一个房子的距离。
    2. 遍历所有房子的垃圾,找到每种垃圾最后出现的房子的位置。

    时间复杂度

    遍历所有房子的垃圾,故时间复杂度为 O(nL)

    空间复杂度

    仅需要常数的额外空间。

    class Solution {
    public:
        int garbageCollection(vector<string>& gar, vector<int>& tra) {
            int n = gar.size();
            int ans = 0, metal_far = 0, paper_far = 0, glass_far = 0;
            
            for(int i = 0; i < n; i++){
                ans += gar[i].size();
                for(auto c : gar[i]){
                    if(c == 'M')  metal_far = i;
                    else if(c == 'P') paper_far = i;
                    else  glass_far = i;
                }
            }
            
            for(int i = 1; i < n - 1; i++) tra[i] += tra[i - 1];
            if(metal_far > 0) ans += tra[metal_far - 1];
            if(paper_far > 0) ans += tra[paper_far - 1];
            if(glass_far > 0) ans += tra[glass_far - 1];
            return ans;
        }
    };
    

    2392. 给定条件下构造矩阵

    (拓扑排序) O(k+m)

    1. 分别对行和列进行拓扑排序,求出每个数字所在的排名。
    2. 如果拓扑排序不存在,则说明答案不存在。
    3. 按照行和列的排名填充最终的矩阵。

    时间复杂度

    两次拓扑排序的时间复杂度为 O(k+m),其中 m 为条件的长度。
    填充答案仅需要 O(k) 的时间。(忽略新建 \(k^2\) 零矩阵的时间。)

    空间复杂度

    需要 \(O(k^2)\) 的额外空间存储拓扑排序的数据结构和答案。

    class Solution {
    public:
        vector<int> topSort(int k, vector<vector<int>>& condition){
            vector<vector<int>> son(k + 1);
            vector<int> in(k + 1);
            
            for(auto &c : condition){
                int a = c[0], b = c[1];
                son[a].push_back(b);
                ++in[b];
            }
            
            vector<int> q(410);
            int hh = 0, tt = -1;
            
            for(int i = 1; i <= k; i++)
                if(!in[i])
                    q[++tt] = i;
            
            while(hh <= tt){
                int t = q[hh++];
                for(int u : son[t])
                    if(!--in[u])
                        q[++tt] = u;
            }
            if(tt != k - 1) return {};
            return q;
        }
        
        int get(vector<int> &w, int t){
            for(int i = 0; i < w.size(); i++)
                if(w[i] == t)
                    return i;
            return 0;
        }
        
        vector<vector<int>> buildMatrix(int k, vector<vector<int>>& row, vector<vector<int>>& col) {
            auto r = topSort(k, row), c = topSort(k, col);
            if(r.size() < k || c.size() < k) return {};
            vector<vector<int>> ans(k, vector<int>(k));
            for(int i = 1; i <= k; i++)
                ans[get(r, i)][get(c, i)] = i;
            return ans;
        }
    };
    
  • 相关阅读:
    html <applet>元素属性介绍
    C#内存释放(转)
    mongodb for linux (安装)
    WCF客户端搭建(通过自定义WCF Client封装) wu
    SQL常用语句 wu
    任务调度平台 wu
    将DataSet 纵向显示数据
    关于OP和SI项目的记录点,防止遗忘难以查找
    java进阶
    git代码量统计
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/16710938.html
Copyright © 2020-2023  润新知