LeetCode 第293场周赛

总结

再接再厉,争取早日上2000分

5234. 移除字母异位词后的结果数组

第一题判断一下上一个位置是否一样的,如果一样的就跳过,否则加入答案,可以排序比较是否相同。

// shiran
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, n) for (int i = a; i < n; i++)
#define per(i, n, a) for (int i = n - 1; i >= a; i--)
#define sz(x) (int)size(x)
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define pb push_back
#define mk make_mair
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9+7;
const int N = 200010, M = 300010;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

class Solution {
public:
    vector<string> removeAnagrams(vector<string>& words) {
        set<string> S;
        vector<string> ans;
        string p;
        for (int i = 0; i < sz(words); i ++ )
        {
            if (i)
            {
                string t = words[i];
                sort(all(t));
                if (t != p) ans.pb(words[i]);
                p = t;
            }
            else
            {
                ans.pb(words[i]);
                p = words[i];
                sort(all(p));
            }
        }
        return ans;
    }
};

6064. 不含特殊楼层的最大连续楼层数

这道题比较坑的一点是端点可以算进去。因此比较特殊楼层差最大值后,再比较一下端点即可

// shiran
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, n) for (int i = a; i < n; i++)
#define per(i, n, a) for (int i = n - 1; i >= a; i--)
#define sz(x) (int)size(x)
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define pb push_back
#define mk make_mair
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9+7;
const int N = 200010, M = 300010;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

class Solution {
public:
    int maxConsecutive(int l, int r, vector<int>& v) {
        // v.pb(l), v.pb(r);
        sort(all(v));
        
        int ans = 0;
        rep(i, 0, sz(v) - 1)
        {
            ans = max(ans, v[i + 1] - v[i] - 1);
        }
        ans = max(ans, max(v[0] - l, r - v[sz(v) - 1]));
        return ans;
    }
};

6065. 按位与结果大于零的最长组合

这道题是一道思维题,按位与的本质是比较二进制中1的个数,那么这道题就转化为每一个数第i位出现了多少个1,返回出现最多的那一位1的个数就是答案。

// shiran
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, n) for (int i = a; i < n; i++)
#define per(i, n, a) for (int i = n - 1; i >= a; i--)
#define sz(x) (int)size(x)
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define pb push_back
#define mk make_mair
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9+7;
const int N = 35, M = 300010;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

int a[N];
class Solution {
public:
    int largestCombination(vector<int>& v) {
        memset(a, 0, sizeof a);
        for (auto t: v)
        {
            int k = 0;
            while (t) {
                a[k ++ ] += t & 1;
                t >>= 1;
            }
        }
        
        int ans = 0;
        rep(i, 0, 32)
            ans = max(ans, a[i]);
        return ans;
    }
};

6066. 统计区间中的整数数目

最后一题也有点思维的味道在里面,其实是区间合并的扩展。用一个集合维护不相交区间的端点,用set排序,每一次插入,其实就是比较跟前后区间交集,每次合并前后的区间即可

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
// shiran
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, n) for (int i = a; i < n; i++)
#define per(i, n, a) for (int i = n - 1; i >= a; i--)
#define sz(x) (int)size(x)
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define pb push_back
#define mk make_pair
typedef long long ll;
typedef pair<int, int> PII;
const int mod = 1e9+7;
const int N = 100010, M = 300010;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

class CountIntervals {
set<PII> S;
int k = 0;
public:
    CountIntervals() {
    S.clear();
    k = 0;
    }
    
    void add(int l, int r) {
        auto p = mk(l, r);
        while (true)
        {   
            auto it = S.lower_bound(p);
            if (it != S.end() && it->fi <= r) {
                k -= (it->se - it->fi + 1);
                p.fi = min(p.fi, it->fi);
                p.se = max(it->se, p.se);
                S.erase(it);
            }
            else break;
        }
        auto it = S.lower_bound(p);
        if (it != S.begin())
        {
            it -- ;
            if (l <= it->se)
            {
                k -= (it->se - it->fi + 1);
                p.fi = min(p.fi, it->fi);
                p.se = max(it->se, p.se);
                S.erase(it);
            }
           
        }
        k += p.se - p.fi + 1;
        S.insert(p);
    }
    
    int count() {
        //for (auto& t : S)
        //    printf("%d %d\n", t.fi, t.se);
        return k;
    }
};

/**
 * Your CountIntervals object will be instantiated and called as such:
 * CountIntervals* obj = new CountIntervals();
 * obj->add(left,right);
 * int param_2 = obj->count();
 */
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shirandexiaowo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值