Leetcode 175场周赛

2020-02-09 22:44:14

5332. 检查整数及其两倍数是否存在

给你一个整数数组 arr,请你检查是否存在两个整数 N 和 M,满足 N 是 M 的两倍(即,N = 2 * M)。

更正式地,检查是否存在两个下标 i 和 j 满足:

i != j
0 <= i, j < arr.length
arr[i] == 2 * arr[j]

我的方法:用了两个map,两个vector,还用了排序,有些麻烦:

我的想法是从前到后遍历的话,后面一定要是前面的两倍,否则无法判断:

class Solution {
public:
    bool checkIfExist(vector<int>& arr) {
        vector<int> pos,neg;
        map<int,int> mp;
        int n = arr.size();
        for(int i = 0;i < n;i++){
            if(arr[i] > 0) pos.push_back(arr[i]);
            else neg.push_back(arr[i]);
        }
        sort(pos.begin(),pos.end());
        sort(neg.begin(),neg.end(),greater<int>());
        int n1 = pos.size();
        int n2 = neg.size();
        map<int,int> mp2;
        for(int i = 0; i < n1; i++){
            if(mp.count(pos[i]) == 0) mp[pos[i]*2] = 1;
            else return true;
        }
        for(int i = 0; i < n2; i++){
            if(mp.count(neg[i]) == 0) mp[neg[i]*2] = 1;
            else return true;
        }
        return false;
    }
};

直接暴力:(数据量少,不会超时)

class Solution {
public:
    bool checkIfExist(vector<int>& arr) {
        int n = arr.size();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i != j && arr[i] == 2 * arr[j]) {
                    return true;
                }
            }
        }
        return false;
    }
};

巧妙做法:遍历两遍,思路是全部存入map并标记为1,然后之后如果找不到的就会标记为0;

class Solution {
    map<int,int> m;
public:
    bool checkIfExist(vector<int>& arr) {
        m.clear();
        for(auto i:arr)m[i]++;//先全部存入map,设置为1
        if(m[0]>1)return 1;//区分0和非0;
        for(auto i:arr)if(i&&m[2*i])return 1;//非0时,能找到2*i,则返回;
        return 0;
    }
};

5333. 制造字母异位词的最小步骤数

给你两个长度相等的字符串 s 和 t。每一个步骤中,你可以选择将 t 中的 任一字符 替换为 另一个字符。

返回使 t 成为 s 的字母异位词的最小步骤数。

字母异位词 指字母相同,但排列不同的字符串。

只需要统计s中所有字符与t中的差即可:结果只需t比s少的字符即可(多的可以转换)

class Solution {
public:
    int minSteps(string s, string t) {
        int a[26],b[26];
        for(int i = 0;i < 26; i++) a[i] = b[i] = 0;
        int n = s.size();
        for(int i = 0; i < n; i++){
            a[s[i]-‘a‘]++;
            b[t[i]-‘a‘]++;
        }
        int count = 0;
        int res = 0;
        for(int i = 0; i < 26; i++){
            if(b[i] > a[i]) count += b[i] - a[i];
            else res += a[i] - b[i];
        }return res;
    }

};

1348. 推文计数

请你实现一个能够支持以下两种方法的推文计数类 TweetCounts:

1. recordTweet(string tweetName, int time)

记录推文发布情况:用户 tweetName 在 time(以 秒 为单位)时刻发布了一条推文。
2. getTweetCountsPerFrequency(string freq, string tweetName, int startTime, int endTime)

返回从开始时间 startTime(以 秒 为单位)到结束时间 endTime(以 秒 为单位)内,每 分 minute,时 hour 或者 日 day (取决于 freq)内指定用户 tweetName 发布的推文总数。
freq 的值始终为 分 minute,时 hour 或者 日 day 之一,表示获取指定用户 tweetName 发布推文次数的时间间隔。
第一个时间间隔始终从 startTime 开始,因此时间间隔为 [startTime, startTime + delta*1>,  [startTime + delta*1, startTime + delta*2>, [startTime + delta*2, startTime + delta*3>, ... , [startTime + delta*i, min(startTime + delta*(i+1), endTime + 1)>,其中 i 和 delta(取决于 freq)都是非负整数。

做了很久都没做出来,然后看结果才发现少了一个判断条件:

不过做法也比较麻烦,每次都要排序;

class TweetCounts {
public:
    TweetCounts() {
    }

    void recordTweet(string tweetName, int time) {
        mp[tweetName].push_back(time);
        sort(mp[tweetName].begin(),mp[tweetName].end());
    }
    vector<int> getTweetCountsPerFrequency(string freq, string tweetName, int startTime, int endTime) {
        vector<int> res;
        vector<int> temp = mp[tweetName];
        int fre = freq == "minute"? 60: freq == "hour"? 3600:3600*24;
        int s = lower_bound(temp.begin(),temp.end(),startTime)-temp.begin();
        for(int i = startTime; i <=endTime; i+=fre){
            int c = 0;
            //比赛时少了 temp[s] <= endTime,导致最后一个时间段会出错;
            while(s < temp.size() && temp[s] - i < fre && temp[s] <= endTime) {
                            c++;s++;}
            res.push_back(c);
        }
        return res;
    }
private:
    map<string,vector<int>> mp;
};

比较好的解法:直接确定时间段的长度,这样就可以不用排序直接遍历;

class TweetCounts {
    map<string, vector<int> > mp;
public:
    TweetCounts() {
        mp.clear();
    }

    void recordTweet(string tweetName, int time) {
        mp[tweetName].push_back(time);
    }

    vector<int> getTweetCountsPerFrequency(string freq, string tweetName, int startTime, int endTime) {
        int delta = freq == "minute" ? 60 : freq == "hour" ? 3600 : 86400;
        vector<int> ans((endTime - startTime) / delta + 1);//确定时间段长度
        for (auto i : mp[tweetName]) {
            if (startTime <= i && i <= endTime)
                ++ans[(i - startTime) / delta];
        }
        return ans;
    }
};

5335. 参加考试的最大学生数

给你一个 m * n 的矩阵 seats 表示教室中的座位分布。如果座位是坏的(不可用),就用 ‘#‘ 表示;否则,用 ‘.‘ 表示。

学生可以看到左侧、右侧、左上、右上这四个方向上紧邻他的学生的答卷,但是看不到直接坐在他前面或者后面的学生的答卷。请你计算并返回该考场可以容纳的一起参加考试且无法作弊的最大学生人数。

学生必须坐在状况良好的座位上。

这题直接不会,应该是回溯,但是不会写:

看题解是状态压缩dp,又是一个没听过的东东:

原文地址:https://www.cnblogs.com/Aliencxl/p/12289212.html

时间: 2024-08-01 05:01:38

Leetcode 175场周赛的相关文章

Leetcode 第175场周赛 题解(完结)

Leetcode 第175场周赛 题解 检查整数及其两倍数是否存在 数据范围小的可怜,\(O(n^2)\) 解法可行.如果范围大一点,可以先进行排序然后遍历每一个数进行二分查找,时间复杂度 \(O(nlogn)\) 代码是平方解法. typedef long long ll; typedef double db; #define _for(i,a,b) for(int i = (a);i < b;i ++) #define _rep(i,a,b) for(int i = (a);i > b;i

Leetcode 183场周赛

Leetcode 183场周赛 1 #include <algorithm> class Solution { public: vector<int> minSubsequence(vector<int>& nums) { sort(nums.begin(), nums.end());//升序排列 vector<int> ans; int sum[505]; memset(sum,0,sizeof(sum)); sum[0] = nums[0]; f

LeetCode 第 165 场周赛

LeetCode 第 165 场周赛 5275. 找出井字棋的获胜者 5276. 不浪费原料的汉堡制作方案 5277. 统计全为 1 的正方形子矩阵 5278. 分割回文串 III C 暴力做的,只能说数据不充分 找出井字棋的获胜者4 题目描述 Description A 和 B 在一个 3 x 3 的网格上玩井字棋. 井字棋游戏的规则如下: 玩家轮流将棋子放在空方格 (" ") 上. 第一个玩家 A 总是用 "X" 作为棋子,而第二个玩家 B 总是用 "

Leetcode 第174场周赛 题解

Leetcode 第174场周赛 题解 方阵中战斗力最弱的 K 行 签到题,统计一下每行的军人数量,然后设置一下排序规则即可. 时间复杂度 \(O(nlogn)\) typedef long long ll; typedef double db; #define _for(i,a,b) for(int i = (a);i < b;i ++) #define _rep(i,a,b) for(int i = (a);i > b;i --) #define INF 0x3f3f3f3f3f3f3f3

LeetCode 第 183 场周赛

LeetCode 第 183 场周赛 非递增顺序的最小子序列 降序排列后,往 vector<int>ans 中添加元素,直到其和超过所有元素和的一半. class Solution { public: vector<int> minSubsequence(vector<int>& nums) { const int n = nums.size(); sort(nums.begin(), nums.end(), greater<int>()); int

LeetCode-第 166 场周赛

LeetCode-第 166 场周赛 1281.subtract-the-product-and-sum-of-digits-of-an-integer 1282.group-the-people-given-the-group-size-they-belong-to 1283.find-the-smallest-divisor-given-a-threshold 1284.minimum-number-of-flips-to-convert-binary-matrix-to-zero-matr

Leetcode 5379. 石子游戏 III(第183场周赛)

题目内容 Alice 和 Bob 用几堆石子在做游戏.几堆石子排成一行,每堆石子都对应一个得分,由数组 stoneValue 给出. Alice 和 Bob 轮流取石子,Alice 总是先开始.在每个玩家的回合中,该玩家可以拿走剩下石子中的的前 1.2 或 3 堆石子 .比赛一直持续到所有石头都被拿走. 每个玩家的最终得分为他所拿到的每堆石子的对应得分之和.每个玩家的初始分数都是 0 .比赛的目标是决出最高分,得分最高的选手将会赢得比赛,比赛也可能会出现平局. 假设 Alice 和 Bob 都采

LeetCode第136场周赛

菜鸡我只做出了一道... 5055. 困于环中的机器人 在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方.机器人可以接受下列三条指令之一: "G":直走 1 个单位 "L":左转 90 度 "R":右转 90 度 机器人按顺序执行指令 instructions,并一直重复它们. 只有在平面中存在环使得机器人永远无法离开时,返回 true.否则,返回 false. 提示: 1 <= instructions.length <=

LeetCode 第133场周赛总结

1029. 两地调度 公司计划面试 2N 人.第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costs[i][1]. 返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达. 示例: 输入:[[10,20],[30,200],[400,50],[30,20]] 输出:110 解释: 第一个人去 A 市,费用为 10. 第二个人去 A 市,费用为 30. 第三个人去 B 市,费用为 50. 第四个人去 B 市,费用为 20. 最低总费用为 10 + 30