LeetCode第302场周赛

Posted William_Tao(攻城狮)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode第302场周赛相关的知识,希望对你有一定的参考价值。

LeetCode第 302 场周赛

第 302 场周赛

我走得很慢!但我从不后退!

6120. 数组能形成多少数对

思路:
如果元素成对出现,那么一定能被2整除,因此,我们把数组中出现的数字的个数存储下来,然后遍历map,对map中个元素进行除2操作,能被2整除的即是start,不能被2整除的就是剩余的元素个数。

class Solution 
public:
    vector<int> numberOfPairs(vector<int>& nums) 
       map<int,int> mp;
       for(int i=0;i<nums.size();i++)mp[nums[i]]++;
       int start=0,end=0;
       for(auto&[x,y]:mp)
           //cout<<y<<"-";
           start+=y/2;
           end += y%2;
        
       return vector<int>start,end;
    
;

6164. 数位和相等数对的最大和

思路:
1.求每个数的数位和
2.map存数位和以及当前数位和下的最大数字(贪心)
3.更新答案。

class Solution 
public:
    int maximumSum(vector<int>& nums) 
        //这样子的map是关键
        unordered_map<int,vector<int>>mp;
        // 计算每个数的数位和并放入 map
        for (int x : nums) 
            int t = 0;
            for (int y = x; y; y /= 10) t += y % 10;
            //对应位数和下所存储的数组
            mp[t].push_back(x);
        
        int ans=-1;
        for(auto it=mp.begin();it!=mp.end();it++)
            //如果当前位数和下的数组长度大于一
            if(it->second.size()>1)
                //进行排序,优先取最大的两个进行相加
                sort(it->second.begin(),it->second.end());
                int sz=it->second.size();
                //取整体最大的
                ans=max(ans,it->second[sz-1]+it->second[sz-2]);
            
        
        return ans;
    
;

6121. 裁剪数字后查询第 K 小的数字

思路:
本题的核心是将裁剪后的字符串以及对应的下标绑定起来,然后进行一个排序,因此可以用pair来存储裁剪后的字符串以及对应的下标信息,再通过vector进行排序。

  1. 首先,遍历queries,得到k和trim
  2. 然后再次基础上遍历nums,得到对应截取后的字符串以及下标,存入vector<pair<string,int>>当中
  3. 对vector<pair<string,int>>进行排序
  4. 最后,找到 nums 中第 ki 小数字对应的下标
class Solution 
public:
    vector<int> smallestTrimmedNumbers(vector<string>& nums, vector<vector<int>>& queries) 
        vector<int> ans(queries.size(),0);
        //记录每个字符串的长度为多少
        int nSize = nums[0].size();
        //循环遍历query
        for(int i=0;i<queries.size();i++)
            //得到二维数组中每一行的k和trim
            int k = queries[i][0];
            int trim=queries[i][1];
            //存取截取的数,以及其下标
            vector<pair<string,int>> t(nums.size());
            //遍历nums,存取截取后的字符串以及对应的下标
            for(int j=0;j<nums.size();j++)
                //string为截取的字符串,int为对应的下标
                t[j] = make_pair(nums[j].substr(nSize-trim),j);
            
            //对vector<pair<string,int>>类型进行排序,这样即可不丢失下标
            //当元素是pair时,vector默认的排序是string比大小
            sort(t.begin(),t.end());
          /*  for(int j=0;j<nums.size();j++)
               cout<<t[j].first<<":"<<t[j].second<<endl;
            */
            //找 nums 中第 ki 小数字对应的下标
            ans[i] = t[k-1].second;
        
        return ans;
    
;

6122. 使数组可以被整除的最少删除次数

思路:
能被一堆数整除就是能被这堆数的最大公约数整除

  1. 首先找到numsDivide中的最大公因子
  2. 在nums(排序好之后)中寻找是否有符合numsDivide中的最大公因子相等的元素(即能够整除的元素),如果有就返回下标。(这就是利用排序之后的好处,这样既可得到最小的删除次数)
class Solution 
public:
    int minOperations(vector<int>& nums, vector<int>& numsDivide) 
        int g=0;
        //求出numsDivide 中最大的公因子
        for(int x:numsDivide)
            g=gcd(g,x);
        
        //cout<<g<<endl;
        //对nums进行排序
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();i++)
            //如果在nums中找到和g相等的元素,就返回当前下标(即最少删除次数)
            if(g%nums[i]==0)return i;
        
        return -1;
    
;

总结

本次周赛难度总体来说其实并不大(相比前几次),但是做的不咋地。
反思总结有以下的问题:
1.对于stl库中map,pair这类并没有很常用,操作起来有点生疏
2.最近一周在外面玩,做题的感觉好像无了(自己菜,还找借口)
3.t1主要是从别的角度考虑(奇偶能否被整除);t2 模拟+贪心,但是是通过 unordered_map<int,vector>mp;来存储数组,之前都是map<int,int>这种;需要学习一下;t3模拟,使用vector<pair<string,int>>来存储剪裁的字符串以及下标,方便排序;t4能被一堆数整除就是能被这堆数的最大公约数整除;使用到gcd的函数

以上是关于LeetCode第302场周赛的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode第302场周赛

LeetCode第 303 场周赛

LeetCode第 303 场周赛

LeetCode第 303 场周赛

LeetCode第304场周赛

LeetCode第304场周赛