leetcode第 134 场双周赛

85 阅读3分钟

链接

总结

这场前三题没啥问题,基本都是看完题就有思路:暴力,贪心,暴力。
最后一题看起来很多人A了,感觉应该是能做出来的,但是不太行,随手猜了个结论写了一下,WA麻了。。
明天补一下

题解

第一题

给定一个值为0和1的循环数据,求有多少个交替组。
交替组的定义:长度为3的子数组且相邻两个元素的值不同。即a[i] != a[i+1]

直接追加前两个元素到数据最后,然后从枚举a[i],a[i+1], a[i+1] (0<=i<n)是否是一个交替组。 时间:O(n)
空间:O(1)

class Solution {
public:
    int numberOfAlternatingGroups(vector<int>& a) {
        a.push_back(a[0]);
        a.push_back(a[1]);
        int n = a.size();
        int ans{};
        for(int i = 0; i + 2 < n; i ++){
            ans += (a[i] == a[i+2] && a[i] != a[i+1]);
        }
        return ans;
        
    }
};

第二题

给定一个数组a, 以及一个数b.我们可以做两种操作:

  1. 选中一个小于b且没有标记过的a[i],分数加一,并且b=b-a[i];
  2. 选中一个没有标记过的a[i], b=b+a[i],并且标记a[i];
    问最多可以得到多少分?
  1. 由于操作1不会标记a[i],因此在操作1中我们可以重复选择a[i]。
  2. 由于得到的分数每次都是加一,因此我们可以考虑每次都取min(a[i]),用最少的代码拿到最多的分数。
  3. 由于我们每次1操作只用到min(a[i]),因此剩余的a[i]我们其实都可以加到b上。

注意需要用long long 计算,不然会G。

比赛的时候排了一下序,其实不用排序的,直接求和以及求最小值就好了。

class Solution {
public:
    using L = long long;
    long long maximumPoints(vector<int>& a, int b_) {
        sort(begin(a), end(a));
        int n = a.size();
        L b = b_;
        if(b < a.front()) return 0;
        for(int i = 1; i < n; i ++){
            b += a[i];
        }
        L ans = b/a[0];
        return ans;
        
    }
};

简化一下
时间:O(n)
空间:O(1)

class Solution {
public:
    using L = long long;
    long long maximumPoints(vector<int>& a, int b) {
        L sum{b}, mi = INT_MAX;
        for(auto ele: a){
            sum += ele;
            mi = min<L>(mi, ele);
        }
        if(mi > b)return 0;
        sum -= mi;
        return sum/mi;
    }
};

第三题

和第一题一样,唯一不同的是第一题的交替组长度为3,第三题的长度为k。

考虑以下几点:

  1. 如果a[i...i+k-1]是一个交替组,那么对于a[i+1...i+k-1]我们是不需要判断的,因为a[i...i+k-1]已经判断过了。所以对于a[i+1...i+k-1],只需要判断a[i+k-1]!=a[i+k]。
  2. 如果a[i...j]是一个交替组,但是a[i...j+1]不是一个交替组,显然a[j]==a[j+1],那么以a[i]..a[j]开头的子数组都不可能是交替组。因为会包含a[j]和a[j+1]。

基于上面两点:直接枚举a[i],并且记录a[i-1...i-1+k-1]是否是交替组。

  • 如果a[i-1...i-1+k-1]是交替组,那么检查a[i+k-1]!=a[i+k]:
    • 如果不等,则a[i...i+k-1]也是交替组;
    • 如果相等,则直接令i跳到i+k;
  • 如果a[i-1...i-1+k-1]不是交替组,则直接检查a[i...i+k-1]即可:
    • 如果a[i...i+k-1]是交替组,则更新标记
    • 如果不是,直接将i跳转到不符合交替组定义的位置。
class Solution {
public:
    int numberOfAlternatingGroups(vector<int>& a, int k) {
        for(int i = 0; i < k-1; i ++){
            a.push_back(a[i]);
        }
        int ans{};
        int last{};
        int n = a.size();
        for(int i = 0; i+k-1 < n; i ++){
            if(last){
                if(a[i+k-1] != a[i+k-2]){
                    ans++;
                }else{
                    last = 0;
                    i = i+k-2;
                }
                continue;
            }
            int flag = -1;
            for(int j =1; j < k; j ++){
                if(a[i+j] == a[i+j-1]){
                    flag = i+j-1;
                    break;
                }
            }
            if(flag == -1){
                last = 1;
                ans++;
            }else{
                i = flag;
            }
            
        }
        return ans;
        
    }
};