zoukankan      html  css  js  c++  java
  • leetcode 235周赛

    竞赛链接:第 235 场周赛 - 力扣(LeetCode) (leetcode-cn.com)

    题目一:

    1816. 截断句子

    题目描述及示例:

    句子 是一个单词列表,列表中的单词之间用单个空格隔开,且不存在前导或尾随空格。每个单词仅由大小写英文字母组成(不含标点符号)。
    
    例如,"Hello World""HELLO""hello world hello world" 都是句子。
    给你一个句子 s​​​​​​ 和一个整数 k​​​​​​ ,请你将 s​​ 截断 ​,​​​使截断后的句子仅含 前 k​​​​​​ 个单词。返回 截断 s​​​​​​ 后得到的句子。
    
     
    
    示例 1:
    
    输入:s = "Hello how are you Contestant", k = 4
    输出:"Hello how are you"
    解释:
    s 中的单词为 ["Hello", "how" "are", "you", "Contestant"]
    前 4 个单词为 ["Hello", "how", "are", "you"]
    因此,应当返回 "Hello how are you"
    示例 2:
    
    输入:s = "What is the solution to this problem", k = 4
    输出:"What is the solution"
    解释:
    s 中的单词为 ["What", "is" "the", "solution", "to", "this", "problem"]
    前 4 个单词为 ["What", "is", "the", "solution"]
    因此,应当返回 "What is the solution"
    示例 3:
    
    输入:s = "chopper is not a tanuki", k = 5
    输出:"chopper is not a tanuki"
     
    
    提示:
    
    1 <= s.length <= 500
    k 的取值范围是 [1,  s 中单词的数目]
    s 仅由大小写英文字母和空格组成
    s 中的单词之间由单个空格隔开
    不存在前导或尾随空格

    代码:

    class Solution {
    public:
        string truncateSentence(string s, int k) {
            int n = 1;
            string ans;
            for(char x : s)
            {
                if(x == ' ')
                {
                    if(n < k)
                        n++;
                    else
                        break;
                }
                ans += x;     
            }
            return ans;
        }
    };

    题目二:

    1817. 查找用户活跃分钟数

    题目描述及示例:

    给你用户在 LeetCode 的操作日志,和一个整数 k 。日志用一个二维整数数组 logs 表示,其中每个 logs[i] = [IDi, timei] 表示 ID 为 IDi 的用户在 timei 分钟时执行了某个操作。
    
    多个用户 可以同时执行操作,单个用户可以在同一分钟内执行 多个操作 。
    
    指定用户的 用户活跃分钟数(user active minutes,UAM) 定义为用户对 LeetCode 执行操作的 唯一分钟数 。 即使一分钟内执行多个操作,也只能按一分钟计数。
    
    请你统计用户活跃分钟数的分布情况,统计结果是一个长度为 k 且 下标从 1 开始计数 的数组 answer ,对于每个 j(1 <= j <= k),answer[j] 表示 用户活跃分钟数 等于 j 的用户数。
    
    返回上面描述的答案数组 answer 。
    
     
    
    示例 1:
    
    输入:logs = [[0,5],[1,2],[0,2],[0,5],[1,3]], k = 5
    输出:[0,2,0,0,0]
    解释:
    ID=0 的用户执行操作的分钟分别是:525 。因此,该用户的用户活跃分钟数为 2(分钟 5 只计数一次)
    ID=1 的用户执行操作的分钟分别是:23 。因此,该用户的用户活跃分钟数为 2
    2 个用户的用户活跃分钟数都是 2 ,answer[2] 为 2 ,其余 answer[j] 的值都是 0
    示例 2:
    
    输入:logs = [[1,1],[2,2],[2,3]], k = 4
    输出:[1,1,0,0]
    解释:
    ID=1 的用户仅在分钟 1 执行单个操作。因此,该用户的用户活跃分钟数为 1
    ID=2 的用户执行操作的分钟分别是:23 。因此,该用户的用户活跃分钟数为 2
    1 个用户的用户活跃分钟数是 11 个用户的用户活跃分钟数是 2 
    因此,answer[1] = 1 ,answer[2] = 1 ,其余的值都是 0
     
    
    提示:
    
    1 <= logs.length <= 104
    0 <= IDi <= 109
    1 <= timei <= 105
    k 的取值范围是 [用户的最大用户活跃分钟数, 105]

    题目分析:

    用哈希表找人和分钟的对应关系使用集合记录活跃人数

    代码:

    class Solution {
    public:
        vector<int> findingUsersActiveMinutes(vector<vector<int>>& logs, int k) {
            unordered_map<int,unordered_set<int>> record;
            for(vector<int> us : logs){
                record[us[0]].insert(us[1]);
            }
            
            vector<int> res(k,0);
            for(auto it = record.begin();it!=record.end();it++){
                res[it->second.size()-1]++;
            }
            return res;
        }
    };

    题目三:

    1818. 绝对差值和

    题目描述及示例:

    给你两个正整数数组 nums1 和 nums2 ,数组的长度都是 n 。
    
    数组 nums1 和 nums2 的 绝对差值和 定义为所有 |nums1[i] - nums2[i]|(0 <= i < n)的 总和(下标从 0 开始)。
    
    你可以选用 nums1 中的 任意一个 元素来替换 nums1 中的 至多 一个元素,以 最小化 绝对差值和。
    
    在替换数组 nums1 中最多一个元素 之后 ,返回最小绝对差值和。因为答案可能很大,所以需要对 109 + 7 取余 后返回。
    
    |x| 定义为:
    
    如果 x >= 0 ,值为 x ,或者
    如果 x <= 0 ,值为 -x
     
    
    示例 1:
    
    输入:nums1 = [1,7,5], nums2 = [2,3,5]
    输出:3
    解释:有两种可能的最优方案:
    - 将第二个元素替换为第一个元素:[1,7,5] => [1,1,5] ,或者
    - 将第二个元素替换为第三个元素:[1,7,5] => [1,5,5]
    两种方案的绝对差值和都是 |1-2| + (|1-3| 或者 |5-3|) + |5-5| = 3
    示例 2:
    
    输入:nums1 = [2,4,6,8,10], nums2 = [2,4,6,8,10]
    输出:0
    解释:nums1 和 nums2 相等,所以不用替换元素。绝对差值和为 0
    示例 3:
    
    输入:nums1 = [1,10,4,4,2,7], nums2 = [9,3,5,1,7,4]
    输出:20
    解释:将第一个元素替换为第二个元素:[1,10,4,4,2,7] => [10,10,4,4,2,7]
    绝对差值和为 |10-9| + |10-3| + |4-5| + |4-1| + |2-7| + |7-4| = 20
     
    
    提示:
    
    n == nums1.length
    n == nums2.length
    1 <= n <= 105
    1 <= nums1[i], nums2[i] <= 105

    题目分析:

    使用 数列一 中的的一个数 替换 数列一中的一个数,只允许替换一次。要求|nums1[i] - nums2[i]|0 <= i < n)的 总和(下标从 0 开始)最小。

    首先替换数列一中最大的数不一定结果最小。

    要找数列一对应数列二中的数,在数列一中最接近的数。而且要求其差值最大话,才能使结果最小。

    可以使用set中内置的二分查找方法lower_bound(),寻找nums1中最接近的nums2[i]的数;

    时间复杂度:O(nlogn)

    代码:

    class Solution {
        typedef long long ll;
        const int mod = 10e9 + 7;
    public:
        int minAbsoluteSumDiff(vector<int>& nums1, vector<int>& nums2) {
        
        set<ll>a;
        ll n = nums1.size(), max_n = 0;
        ll ans = 0;
        ll tem1, tem2;
        set<ll>::iterator flag1;
        for (int i = 0;i < n;i++)
        {
            ans = ans + abs(nums1[i] - nums2[i]);
            a.emplace(nums1[i]);
        }
        for (int i = 0;i < n;i++)
        {
            flag1 = a.lower_bound(nums2[i]);
            tem1 = abs(nums1[i] - nums2[i]);
            tem2 = abs(nums2[i] - *flag1);
            if (flag1 != a.end())
                max_n = max(tem1 - tem2, max_n);
            if (flag1 != a.begin())
                max_n = max(tem1 - abs(nums2[i] - *--flag1), max_n);
        }
        return (ans - max_n) %mod;
        }
    };

    题目四:

    1819. 序列中不同最大公约数的数目

    题目描述及示例:

    给你一个由正整数组成的数组 nums 。
    
    数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数。
    
    例如,序列 [4,6,16] 的最大公约数是 2 。
    数组的一个 子序列 本质是一个序列,可以通过删除数组中的某些元素(或者不删除)得到。
    
    例如,[2,5,10] 是 [1,2,1,2,4,1,5,10] 的一个子序列。
    计算并返回 nums 的所有 非空 子序列中 不同 最大公约数的 数目 。
    
     
    
    示例 1:
    
    
    输入:nums = [6,10,3]
    输出:5
    解释:上图显示了所有的非空子序列与各自的最大公约数。
    不同的最大公约数为 610321 。
    示例 2:
    
    输入:nums = [5,15,40,5,6]
    输出:7
     
    
    提示:
    
    1 <= nums.length <= 105
    1 <= nums[i] <= 2 * 105

    题目分析:

    首先需要找到数列中最大的数,应标记所有数,让结果ANS++(单个数的最大公因数一定是自己) 

    题目是要求所有子序列的最大公约数去重后的个数,观察数量级,肯定不能枚举所有子序列,因此我们可以从另一个角度出发,枚举所有可能的最大公约数,判断是否为某个子序列的公约数。
    因此,我们要解决的问题就是如何判断一个数是否为某个子序列的公约数。
    我们可以采用类似素数筛的方式,枚举每一个数i,判断 “数列中存在的” 2i、3i、4*i…..的公约数是否为i,如果为i,则贡献加一。
    筛法的复杂度为n/1 + n/2 + n/3 + … + n/n,渐进为O(n * logn),而gcd的复杂度为O(logn),所以总复杂度为O(n * logn * logn)。

    作者:simpleqin

    代码:

    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <unordered_map>
    #include <set>
    using namespace std;
    int gcd(int a, int b)//a < b
    {
        while (a % b)
            b ^= a ^= b ^= a %= b;
        return b;
    }
    int main()
    {
        vector<int>nums = { 6, 10, 3 };
        int max = 0;
        int ans = 0;
        bool temp[1000];
        fill(temp, temp + 1000, false);
        for (int x : nums)//找出nums中的最大值并标记所有值
        {
            if (max < x)
                max = x;
            if(temp[x] == false)
            {
                ans++;
                temp[x] = true;
            }
        }
    
        for (int i = 1;i <= max;i++)
        {
            if (temp[i])
                continue;
            int n = 0;
            for (int j = i;j <= max;j+=i)//i和数组的数不断比较判断是否为最小公倍数
            {
                if(temp[j])
                {
                    n = gcd(n, j);
                    if (n == i)
                        break;
                }
    
            }
            if (n == i) ans++;
        }
        cout << ans;
    }
  • 相关阅读:
    ABAP Help Document(2):1.2 表达式
    ABAP Help Document(1):1.1关键字
    api——》将.doc文件转成.docx文件后缀,且仅需要输入单个文件绝对路径
    python 更改默认输出 解决编码常出错问题
    爬取法律法规代码(可直接使用)
    python datetime 模块详解
    python 获得日期列表中最大日期(能够剔出不是日期类型)
    博客园页面css
    日期大小比较令解决{strftime('%Y年%m月%d日')}出错问题
    CodeForces
  • 原文地址:https://www.cnblogs.com/zjw1324399/p/14619618.html
Copyright © 2011-2022 走看看