第89场双周赛

第 89 场双周赛 - 力扣(LeetCode)https://leetcode.cn/contest/biweekly-contest-89/

6208. 有效时间的数目-Easy

题目描述:

给你一个长度为 5 的字符串 time ,表示一个电子时钟当前的时间,格式为 "hh:mm" 。最早 可能的时间是 "00:00" ,最晚 可能的时间是 "23:59" 。

在字符串 time 中,被字符 ? 替换掉的数位是 未知的 ,被替换的数字可能是 0 到 9 中的任何一个。

请你返回一个整数 answer ,将每一个 ? 都用 0 到 9 中一个数字替换后,可以得到的有效时间的数目。

题目解析:

就是分情况讨论即可,但是竞赛情况下抢时间会少考虑很多情况反而耽误了更多时间,我大概wa了四次才通过,代码如下:

class Solution {
public:
    int countTime(string time) {
        int datah = 1;
        int datam = 1;
        if(time[0]=='?'&&time[1]!='?'){
            if(time[1]>'4'||(time[1]=='4'&&(time[3]!='0'||time[4]!='0')))datah = 2;
            else datah = 3;
        }
        if(time[0]=='2'&&time[1]=='?'){
            datah = 4;
            if(time[3]=='0'&&time[4]=='0')datah++;
        }
        if(time[0]=='1'&&time[1]=='?')datah = 10;
        if(time[0]=='0'&&time[1]=='?')datah = 10;
        if(time[0]=='?'&&time[1]=='?'){
            datah = 24;
            if(time[3]=='0'&&time[4]=='0')datah++;
        }
        
        if(time[3]!='?'&&time[4]!='?')datam = 1;
        else if(time[3]=='?'&&time[4]=='?')datam = 60;
        else if(time[3]=='0'&&time[4]=='?')datam = 10;
        else if(time[3]=='1'&&time[4]=='?')datam = 10;
        else if(time[3]=='2'&&time[4]=='?')datam = 10;
        else if(time[3]=='3'&&time[4]=='?')datam = 10;
        else if(time[3]=='4'&&time[4]=='?')datam = 10;
        else if(time[3]=='5'&&time[4]=='?')datam = 10;
        else if(time[3]=='6'&&time[4]=='?')datam = 1;
        else datam = 6;
        return datah*datam;
        
    }
};

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:5.8 MB, 在所有 C++ 提交中击败了100.00%的用户


6209. 二的幂数组中查询范围内的乘积-Medium

题目描述:

给你一个正整数 n ,你需要找到一个下标从 0 开始的数组 powers ,它包含 最少 数目的 2 的幂,且它们的和为 n 。powers 数组是 非递减 顺序的。根据前面描述,构造 powers 数组的方法是唯一的。

同时给你一个下标从 0 开始的二维整数数组 queries ,其中 queries[i] = [lefti, righti] ,其中 queries[i] 表示请你求出满足 lefti <= j <= righti 的所有 powers[j] 的乘积。

请你返回一个数组 answers ,长度与 queries 的长度相同,其中 answers[i]是第 i 个查询的答案。由于查询的结果可能非常大,请你将每个 answers[i] 都对 109 + 7 取余 。

题目解析:

先计算出数n的位数,比如n=15时,将其转为二进制为1111,这样通过位运算可以计算得到n=1+2+4+8。同理,我们先将n进行相应的位运算得到power数组,然后根据queries数组的数据来进行计算即可,注意要在计算中使用long类型,并进行余数计算不然会超出数值范围,代码如下:

class Solution {
public:
    vector<int> productQueries(int n, vector<vector<int>>& queries) {
        int temp = 1;
        vector<int> power;
        vector<int> res(queries.size());
        while(n>0){
            if((n&1)==1)power.push_back(temp);
            n>>=1;
            temp*=2;
        }
        for(int i = 0 ; i<queries.size() ; i++){
            long cur = 1;
            for(int j = queries[i][0] ; j<=queries[i][1] ; j++){
                cur *= power[j];
                cur %= 1000000007;
            }
            res[i] = cur;
        }
        return res;
    }
};

执行用时:368 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:136.9 MB, 在所有 C++ 提交中击败了100.00%的用户


6210. 最小化数组中的最大值-Medium

题目描述:

给你一个下标从 0 开始的数组 nums ,它含有 n 个非负整数。

每一步操作中,你需要:

选择一个满足 1 <= i < n 的整数 i ,且 nums[i] > 0 。
将 nums[i] 减 1 。
将 nums[i - 1] 加 1 。
你可以对数组执行 任意 次上述操作,请你返回可以得到的 nums 数组中 最大值 最小 为多少。

题目解析:

因为进行的操作就是将目前的数减1,然后该数的前一个数加1,就相当于一个匀数,什么时候能够产生最小的最大值呢,就是将所有数进行平均过后不能产生更大的数了,那么这个数就是要求的结果。比如我认为结果值应该为k,那么我用一个数来计算前面的数的容纳能力,即如果这个数小于k,那么这位数能够容纳k-nums[i],如果大于等于k,那么需要将容纳能力减去nums[i]-k,如果容纳能力不够减,说明这个k值不能满足通过移位产生最大值为k,那么我们就需要增大k值,否则我们需要减小k值,直到k恰好满足的情况。代码如下:

class Solution {
public:
    int minimizeArrayValue(vector<int>& nums) {
        int res = nums[0];
        int temp = 0;
        int idx = 0;
        int len = nums.size();
        for(int i = 0 ; i<len ; i++){
            if(nums[i]>nums[0]){
                temp = nums[i];
                idx = i;
                break;
            }
        }
        long sum = 0;
        for(int i = 0 ; i<=idx ; i++){
            sum += nums[i];
        }
        int ys = sum%(idx+1);
        for(int i = 0 ; i<ys ; i++){
            nums[i] = sum/(idx+1)+1;
        }
        for(int i = ys ; i<=idx ; i++){
            nums[i] = sum/(idx+1);
        }
        temp = 0;
        for(int i = 0 ; i<len ; i++){
            if(nums[i]>nums[0]){
                temp = nums[i];
                idx = i;
                break;
            }
        }
        res = max(res,nums[0]);
        while(temp!=-1){
            sum = 0;
            for(int i = 0 ; i<=idx ; i++){
                sum += nums[i];
            }
            ys = sum%(idx+1);
            for(int i = 0 ; i<ys ; i++){
                nums[i] = sum/(idx+1)+1;
            }
            for(int i = ys ; i<=idx ; i++){
                nums[i] = sum/(idx+1);
            }
            temp = -1;
            for(int i = 0 ; i<len ; i++){
                if(nums[i]>nums[0]){
                    temp = nums[i];
                    idx = i;
                    break;
                }
            }
            res = max(res,nums[0]);
        }
        return res;
    }
};

只要导致了时间超时,所以使用二分法进行k值查找可以解决这个问题,代码如下:

class Solution {
public:
    bool check(vector<int>& nums , int k){
        long burden = 0;
        for(int i = 0 ; i<nums.size() ; i++){
            if(nums[i]<k)burden += k-nums[i];
            else{
                if((nums[i]-k)>burden)return false;
                burden -= (nums[i]-k);
            }
        }
        return true;
    }

    int minimizeArrayValue(vector<int>& nums) {
        int minD = 0;
        int maxD = *max_element(nums.begin(),nums.end());
        while(minD<maxD){
            int mid = ((maxD-minD)>>1)+minD;
            if(check(nums,mid))maxD = mid;
            else minD = mid+1;
        }
        return minD;
    }
};

执行用时:152 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:69.5 MB, 在所有 C++ 提交中击败了100.00%的用户

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值