LeetCode235周赛

本文介绍了三个Python编程和算法问题的解决方案。首先是一个简单的截断句子的函数,然后是查找用户活跃分钟数的方法,使用了map和set数据结构。最后讨论了一个绝对差值和的算法,需要使用O(NlogN)的时间复杂度来正确解决。文章还提到了一个关于序列中不同最大公约数的计数问题,通过枚举和最大公约数计算来解答。
摘要由CSDN通过智能技术生成

5722.截断句子

对python来说太方便了。

class Solution:
    def truncateSentence(self, s: str, k: int) -> str:
        return " ".join(s.split()[:k])

5723.查找用户活跃分钟数

当时写的时候觉得map里嵌套一个set可能无法实现,但是看了别人的代码发现是可以的,我这个写法可能有点麻烦。

不过还好没超时,相当于线性查找最小值,如果用set的话插入过程中应该是logn

class Solution {
public:
    vector<int> findingUsersActiveMinutes(vector<vector<int>>& logs, int k) {
        int n=logs.size();
        vector<int>res(k,0);
        map<int,vector<int>>mp;
        map<int,int>mp1;
        for(int i=0;i<n;i++){
            mp[logs[i][0]].push_back(logs[i][1]);
        }
        for(auto c : mp)
        {
            int t=INT_MAX;
            for(int i=0;i<c.second.size();i++){
                mp1[c.second[i]]++;
            }
            res[mp1.size()-1]++;
            mp1.clear();
        }
        return res;
    }
};

5724.绝对差值和

这个题看评论区很多人写的O(n)的贪心:找到影响绝对值最大的进行替换。

但是这个贪心是不正确的,但是测试数据太水都过了,不知道这次会使rejudge还是unrated。

正确的做法应该是O(NlogN),首先求出原数组的绝对差值和,然后再次遍历,利用二分查找,找到nums1中最接近nums2[i]的数,然后求得绝对值差,然后从原来的和中减去原有的和加上这个,然后每次取最小值。

注意好边界问题

class Solution {
public:
    const int MOD=1e9+7;
    int minAbsoluteSumDiff(vector<int>& nums1, vector<int>& nums2) {
        int n=nums1.size();
        long long res=0;
        for(int i=0;i<n;i++){
            res+=abs(nums1[i]-nums2[i]);
        }
        long long sum=res;
        vector<int>a=nums1;
        sort(a.begin(),a.end());
        for(int i=0;i<n;i++)
        {
            int t=n-1;
            if(lower_bound(a.begin(),a.end(),nums2[i])!=a.end()){
                t=lower_bound(a.begin(),a.end(),nums2[i])-a.begin();
            }
            int num1=a[t];
            if(t>0){
                int num2=a[t-1];
                int cha1=abs(num1-nums2[i]);
                int cha2=abs(num2-nums2[i]);
                res=min(res,min(sum-abs(nums1[i]-nums2[i])+cha1,sum-abs(nums1[i]-nums2[i])+cha2));
            }
            else{
                int cha1=abs(num1-nums2[i]);
                res=min(res,sum-abs(nums1[i]-nums2[i])+cha1);
                cout<<res<<endl;
            }
        }
        return res%MOD;
    }
};

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

换个思路,最大公约数一定小于这些数,所以我们可以枚举从1到最大值,这些数都可能成为序列中的最大公约数,那么如果一个数的最大公约数是x,那么它一定是x的倍数,所以遍历x的倍数,如果这个数存在于数组中,那么就求最大公约数,如果最大公约数等于x,那么就符合条件,res+1

class Solution {
public:
    int countDifferentSubsequenceGCDs(vector<int>& nums) {
        int n=nums.size();
        vector<bool>check(2e5+1);
        int mmx=0;
        for(int i=0;i<n;i++)
        {
            mmx=max(nums[i],mmx);
            check[nums[i]]=true;
        }
        int res=0;
        for(int i=1;i<=mmx;i++)
        {
            int sum=0;
            for(int j=i;j<=mmx;j+=i){
                if(check[j]){
                    if(sum==0) sum=j;
                    else sum=__gcd(sum,j);
                    if(sum==i){
                        res++;
                        break;
                    }
                }
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值