返回顶部

LeetCode第271场周赛

T15952. 环和杆

题目描述:给你最多九根杆子,每个杆子上有若干红色、绿色、蓝色的环,问你含有三种颜色的环的杆子的数量

思路:根据题意模拟即可,可以使用set辅助实现

时间复杂度:\(O(n)\)

参考代码:

class Solution {
public:
    int countPoints(string rings) {
        set<char>s[10];
        int n = rings.size();
        for(int i = 0 ; i < n ; i += 2){
            char c = rings[i];
            int idx = rings[i + 1] - '0';
            s[idx].insert(c);
        }
        int res = 0;
        for(int i = 0 ; i <= 9 ; ++i) if(s[i].size() == 3) ++res;
        return res;
    }
};

T2 5953. 子数组范围和

题目描述:对于数组的所有子数组,求其最大值与最小值的差值的和

思路:考虑到数据量只有\(1000\),可以直接暴力枚举所有子数组,可以使用\(set\)维护最大值和最小值,复杂度是\(O(n^2logn)\),虽然复杂度上是正确的,但在平台上超时了,考虑优化,我们每枚举一个子数组的左起点,再枚举右起点时,下标是单调递增的,所以考虑维护两个变量\(mn , mx\),每次更新右边界时就更新一次他们,同时更新答案即可。

时间复杂度:\(O(n^2)\)

参考代码:

class Solution {
public:
    long long subArrayRanges(vector<int>& nums) {
        long long res = 0;
        int n = nums.size();
        for(int i = 0 ; i < n ; ++i){
            int mn = nums[i] , mx = nums[i];
            for(int j = i + 1 ; j < n ; ++j){
                mn = min(mn , nums[j]);
                mx = max(mx , nums[j]);
                res += mx - mn;
            }
        }
        return res;
    }
};

T3 5954. 给植物浇水 II

题目描述:自己看题目

思路:根据题目模拟,定义左右指针,每次同步更新并根据情况统计答案即可

时间复杂度:\(O(n)\)

参考代码:

class Solution {
public:
    int minimumRefill(vector<int>& plants, int a, int b) {
        int cura = a , curb = b , lr = 0 , rs = plants.size() - 1, res = 0;
        while(lr < rs){
            if(cura < plants[lr]) cura = a - plants[lr] , ++res;
            else cura -= plants[lr];
            if(curb < plants[rs]) curb = b - plants[rs] , ++res;
            else curb -= plants[rs];
            ++lr;
            --rs;
        }
        if(lr == rs){
            if(curb > cura){
                if(curb < plants[rs]) ++res;
            }
            else {
                if(cura < plants[lr]) ++res;
            }
        }
        return res;
    }
};

T4 5955. 摘水果

题目描述:在数轴上有一些水果,你在startPos位置,你最多可以走\(k\)步,问你能拿到的水果的最大数目是多少

思路:考虑到水果位置的范围比较小,直接使用数组存储然后做一遍前缀和,我们最优的走法只有两种,先往左走再往右走,和先往右走再往左走。根据该思路模拟即可。

时间复杂度:\(O(max\{pos_i\})\)

参考代码:

class Solution {
public:
    int maxTotalFruits(vector<vector<int>>& fruits, int s, int k) {
        const int N = 2e5 + 5;
        vector<int>sum(N , 0);
        for(auto fruit : fruits) sum[fruit[0] + 1] = fruit[1];
        for(int i = 1 ; i < N ; ++i) sum[i] += sum[i - 1];
        ++s;
        int res = 0;
        for(int i = s; i >= 1 && i + k >= s ; --i){
            int lr = i - 1, rs = s;
            rs = max(rs , s + (k - 2 * (s - i)));
            rs = min(rs , N - 1);
            res = max(res , sum[rs] - sum[lr]);
            //cout << lr << " " << rs << endl;
        }
        for(int i = s ; i < N && i - k <= s ; ++i){
            int rs = i, lr = s;
            lr = min(lr , s - (k - (i - s) * 2));
            lr = max(lr , 1);
            res = max(res , sum[rs] - sum[lr - 1]);
        }
        return res;
    }
};
posted @ 2021-12-12 18:33  cherish-lgb  阅读(12)  评论(0编辑  收藏  举报