力扣第302场周赛补题

第一题:数组能形成多少数对

原题链接

思路:对数组先进行排序,将能构成数对的数区分并统计数量,然后再遍历一次统计剩下的数量,最后返回

class Solution {
public:
    vector<int> numberOfPairs(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int res=0,count=0;
        for(int i=0;i<nums.size()-1;i++){
            if(nums[i]==nums[i+1]){
                nums[i]=-1;
                nums[i+1]=-1;
                res++;
            }
        }
        for(auto k:nums){
            if(k!=-1) count++;
        }
        return {res,count};
    }
};

第二题:​​​​​​​数位和相等数对的最大和

原题链接

思路:用unordered_map来实现,将对应原数组元素的数位和作为key,然后把数位和相同的元素相加,最后返回最大值,如果没有相同的元素则返回-1(借鉴了组长的写法,stl的使用还有很大一部分不会,继续学习!)

class Solution {
public:
    int maximumSum(vector<int>& nums) {
        unordered_map<int,int> mp;
        int res=-1;
        for(auto k:nums){
            int s=k,num=0;
            while(s){
                num+=s%10;
                s/=10;
            }
            if(mp.count(num)) res=max(res,k+mp[num]);//count函数可以判断集合中有没有数位和相同的num
            mp[num]=max(mp[num],k);//更新一下最大值,因为所求和为最大和
        }
        return res;
    }
};

第三题:​​​​​​​ 裁剪数字后查询第 K 小的数字

原题链接

思路:用pair绑定,对nums中的字符串进行排序,然后储存返回即可

class Solution {
public:
    vector<int> smallestTrimmedNumbers(vector<string>& nums, vector<vector<int>>& queries) {
        typedef pair<string,int> PLL;
        int n=nums.size(),m=nums[0].size(),t=queries.size();
        vector<int> ans(t);
        int k=0;
        while(t--){
            vector<PLL> res;
            for(int i=0;i<n;i++){
                string tmp=nums[i].substr(m-queries[k][1],queries[k][1]);//substr的两种用法
                res.push_back({tmp,i});
//push_back是在末尾再添加,如果给res定义为vector<PLL>res(n)就会出现错误,因为前n个都是0
            }
            sort(res.begin(),res.end());
            ans[k]=res[queries[k][0]-1].second;
            k++;
        }
        return ans;
    }
};

第四题:​​​​​​​使数组可以被整除的最少删除次数

思路:对nums进行排序,再来遍历nums中的元素能否整出numsDivide的所有元素,统计不能将目标数组整除的元素个数直到出现可以整除的元素时返回即可,但暴力来时间复杂度为O(n^2),最后几个数据过不了。改用先找出目标数组的最大公约数,其他约数一定可以整除最大公约数,然后再看原数组能否有将其整除元素返回即可

class Solution {
public:
    int gcd(int a,int b){
        return b ? gcd(b,a%b) : a;
    }//求两个数的最大公约数的模板函数

    int minOperations(vector<int>& nums, vector<int>& numsDivide) {
        sort(nums.begin(),nums.end());
        int res=0;
        int tmp=0;
        for(auto k:numsDivide) tmp=gcd(k,tmp);//找到目标数组中的最大公约数
        for(auto k:nums){
            if(tmp%k==0) break;
            else res++;
        }
        if(res==nums.size()) return -1;
        else return res;
    }
};

//超时代码
/*
class Solution {
public:
    int minOperations(vector<int>& nums, vector<int>& numsDivide) {
        sort(nums.begin(),nums.end());
        int res=0,k=0,u=nums.size();
        while(u--){
            bool t=true;
            for(int i=0;i<numsDivide.size();i++){
                if(numsDivide[i]%nums[k]!=0){
                    t=false;
                    break;
                }
            }
            if(t) return res;
            else {
                res++;
                k++;
            }
        }
        return -1;
    }
};
*/

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值