第 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%的用户