一、leetcode双周赛 89
1、6208.有效时间的数目
(1)原题链接:力扣
https://leetcode.cn/problems/number-of-valid-clock-times/
(2)解题思路:
1、枚举即可;
2、小时的取值范围是【0~23】, 分钟的取值范围是【0~59】。
(3)参考代码:
class Solution {
public:
int countTime(string time) {
int res = 1;
if(time[0] == '?' && time[1] == '?') res *= 24;
else if(time[0] == '?') res *= (time[1] <= '3') ? 3 : 2;
else if(time[1] == '?') res *= (time[0] == '2') ? 4 : 10;
if(time[3] == '?') res *= 6;
if(time[4] == '?') res *= 10;
return res;
}
};
2、6209.二的幂数组中查询范围内的乘积
(1)原题链接:力扣
https://leetcode.cn/problems/range-product-queries-of-powers/
(2)解题思路:
1、先求出幂值。
2、再暴力求值即可。
(3)参考代码:
class Solution {
public:
const int mod = 1e9 + 7;
vector<int> productQueries(int n, vector<vector<int>>& queries) {
vector<int> vec;
for(int i = 0 ; i <= 30 ; i ++ )
if((n >> i) & 1 == 1)
vec.push_back(1 << i);
vector<int> ans;
for (auto &q : queries) {
long mult = 1;
for (int i = q[0]; i <= q[1]; i++) {
mult = (mult * vec[i]) % mod;
}
ans.push_back(mult);
}
return ans;
}
};
3、6210.最小化数组中的最大值
(1)原题链接:力扣
https://leetcode.cn/problems/minimize-maximum-of-array/
(2)解题思路:
1、边界条件: dp[0] = nums[0];
2、当加上一个数字 nums[i] 时,sum(0...i)的平均数 avg并没有增大,那么我们保持原状态:dp[i] = dp[i - 1];
3、当平均数 avg > dp[i -1] 时,原来的均匀方式不够大,需要扩大:dp[i] = avg。
==>状态转移方程:
(3)参考代码:
class Solution {
public:
int minimizeArrayValue(vector<int>& nums) {
int n = nums.size();
int dp = nums[0];
long long sum = nums[0];
for(int i = 1; i < n; i ++ ) {
sum += nums[i];
int avg = sum / (i + 1) + (bool) (sum % (i + 1));
if(avg > dp) dp = avg;
}
return dp;
}
};
二、leetcode单周赛 315
1、6204.与对应负数同时存在的最大正整数
(1)原题链接:力扣
https://leetcode.cn/problems/largest-positive-integer-that-exists-with-its-negative/
(2)解题思路:
1、用哈希白存下每个数出现的次数。
2、对数组进行排序。
3、从大到小遍历排序后的数组,找到存在对应负值的满足条件的最大值。
(3)参考代码:
class Solution {
public:
int findMaxK(vector<int>& nums) {
int res = -1;
unordered_map<int, int> mp;
for(auto& a: nums){
mp[a] ++;
}
sort(nums.begin(), nums.end());
int n = nums.size();
for(int i = n - 1; i >= 0; i -- ){
if(nums[i] > 0 && mp.count(-nums[i])) {
res = nums[i];
break;
}
}
return res;
}
};
2、6205.反转之后不同整数的数目
(1)原题链接:力扣
https://leetcode.cn/problems/count-number-of-distinct-integers-after-reverse-operations/
(2)解题思路:
1、通过字符串和整型的相互转换以及字符串的翻转来进行数字的翻转。
2、所有的数字都存到set中,最后返回set的大小即可。
(3)参考代码:
class Solution {
public:
int countDistinctIntegers(vector<int>& nums) {
int n = nums.size();
set<int> res;
for(int i = 0; i < n; i ++ ) {
string s = to_string(nums[i]);
reverse(s.begin(), s.end());
int t = stoi(s);
res.insert(t);
}
for(int i = 0; i < n; i ++ ) {
res.insert(nums[i]);
}
return res.size();
}
};
3、6219.反转之后的数字和
(1)原题链接:力扣
https://leetcode.cn/problems/sum-of-number-and-its-reverse/
(2)解题思路:
利用同T2的反转方式,直接对(0, num)这个区间中的数进行枚举,找到一个满足的数即return true,否则return false。
(3)参考代码:
class Solution {
public:
bool sumOfNumberAndReverse(int num) {
for(int i = 0; i <= num; i ++ ) {
int t = i;
string s = to_string(i);
reverse(s.begin(), s.end());
int t1 = stoi(s);
int res = t + t1;
if(res == num) return true;
}
return false;
}
};
4、6207.统计界定子数组的数目
(1)原题链接:力扣
https://leetcode.cn/problems/count-subarrays-with-fixed-bounds/
(2)解题思路:
1、先找出不在(minK, maxK)范围内的数,答案区间一定是被这些数给划分出来的。
2、如何判断某一段答案区间的满足条件的数目? -> 用双指针(i, j)保证某段答案区间的子区间中包含至少一个minK和一个maxK,假设 j 是这段子区间的左边界,那么也就意味着 j 左边的每个数加入到子区间中都是满足条件的(包含至少一个minK和一个maxK),那么方案数也就是 j + 1个。
3、用一个res保存每次的所得到的方案数, 即可。
(3)参考代码:
class Solution {
public:
long long countSubarrays(vector<int>& nums, int minK, int maxK) {
long long res = 0;
int smin = 0, smax = 0;
for(int i = 0, last = 0, j = 0; i < nums.size(); i ++ ) {
if(nums[i] < minK || nums[i] > maxK) {
j = last = i + 1;
smin = smax = 0;
continue;
}
if(nums[i] == maxK) smax ++;
if(nums[i] == minK) smin ++;
while(j <= i) {
if(nums[j] == minK) smin --;
if(nums[j] == maxK) smax --;
if(!smin || !smax) {
if(nums[j] == minK) smin ++;
if(nums[j] == maxK) smax ++;
break;
}
j ++;
}
if(smin && smax) res += j - last + 1;
}
return res;
}
};