持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
力扣——第 315 场周赛
6204. 与对应负数同时存在的最大正整数 - 力扣(LeetCode)
问题解析
遍历数组,哈希表记录每个元素的出现次数,当遇到正数时看它的负数有没有被哈希表记录过,如果记录过就把这个数存下来,维护最大值。
但是数组是无序的,所以有可能遇到遍历到正数时还没遇到它负数的情况,所以我们可以先对数组排个序再遍历;或者先遍历一次只记录负数,再遍历一次只记录正数。
AC代码
class Solution {
public:
int findMaxK(vector<int>& nums) {
unordered_map<int,int>mymap;
sort(nums.begin(),nums.end());
int mx=-1;
for(auto i:nums)
{
if(i>0)c
{
if(mymap[-1*i]!=0)mx=max(mx,i);
}
mymap[i]=1;
}
return mx;
}
};
6205. 反转之后不同整数的数目 - 力扣(LeetCode)
问题解析
哈希表记录每个数的出现次数。
每遍历到一个数,就把这个数反转过来,然后再用哈希表记录下来。
最后返回哈希表的大小即可。
AC代码
class Solution {
public:
int countDistinctIntegers(vector<int>& nums) {
unordered_map<int,int>mymap;
int n=nums.size();
for(int i=0;i<n;i++)
{
mymap[nums[i]]=1;
int x=nums[i],ans=0;
while(x)
{
ans*=10;
ans+=x%10;
x/=10;
}
mymap[ans]=1;
}
return mymap.size();
}
};
6219. 反转之后的数字和 - 力扣(LeetCode)
问题解析
注意到num最大只有1e5,而且可以知道,如果有个数能满足题目的条件,那么哪个数肯定不会大于num。
所以我们可以从0开始枚举数x,每次再把x翻转过来记作y,判断x+y是否等于num。
有一个能满足就返回true。如果都满足不了就输出false。
复杂度为:O(n*len(n))
AC代码
class Solution {
public:
bool sumOfNumberAndReverse(int num) {
for(int i=0;i<=num;i++)
{
int x=i,ans=0;
while(x)
{
ans*=10;
ans+=x%10;
x/=10;
}
if(ans+i==num)return true;
}
return false;
}
};
6207. 统计定界子数组的数目 - 力扣(LeetCode)
问题解析
双指针+优先队列。
我们用两个优先队列minpos和maxpos来存储遍历过程中,值等于minK和值等于maxK的元素的下标。
- 如果当前数在minK和maxK的范围中,右指针r继续移动。
- 如果当前数不在minK和maxK的范围中,则开始移动左指针l,同时计算一下每个数作为左边界能提供的贡献。
如果minpos和maxpos都不为空,说明当前l到r-1的数组是满足题目要求的。
则当前左指针所能提供的贡献就为:r-max(minpos.top(),maxpos.top());
因为要求数组中同时有minK和maxK,所以数组的右边界最小是他俩中最大的那个下标,然后左指针从这个下标开始到达r指针的这一段距离都可以是左指针提供的贡献。例如:
num={4,2,3,1,4,5,2,7} ,minK=1 ,maxK=5
{4 2 3 1 4 5 2 7}
对于每个左边界,他们提供的数组有: 4 2 3 1 4 5 2
4 2 3 1 4 5
2 3 1 4 5 2
2 3 1 4 5
3 1 4 5 2
3 1 4 5
1 4 5 2
1 4 5
当左指针指向的下标等于minpos.top()或maxpos.top()时,我们将它弹出,然后继续计算。
直到其中有一个队列为空时,因为当前r是不在minK和maxK范围中的,所以当我们把r+1,再直接将l移动到r的位置上,同时情况两个优先队列。双指针再继续移动。
AC代码
class Solution {
public:
long long countSubarrays(vector<int>& nums, int minK, int maxK) {
long long n = nums.size(), l = 0, r = 0, res = 0;
priority_queue<int, vector<int>, greater<int>>mnpos, mxpos;
while (r <= n)
{
if (r == n || nums[r] > maxK || nums[r] < minK)
{
while (l < r)
{
if (mnpos.empty() || mxpos.empty())break;
int x = max(mnpos.top(), mxpos.top());
res += r - x;
if (mnpos.top() == l)mnpos.pop();
if (mxpos.top() == l)mxpos.pop();
l++;
}
while (!mnpos.empty())mnpos.pop();
while (!mxpos.empty())mxpos.pop();
r++;
l=r;
continue;
}
if (nums[r] == minK)mnpos.push(r);
if (nums[r] == maxK)mxpos.push(r);
r++;
}
return res;
}
};