第308场周赛

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

第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;
    }
};
posted @ 2022-09-20 14:27  INnoVation-V2  阅读(2)  评论(0编辑  收藏  举报