题目来源于知识星球—英雄算法联盟,六月算法集训专题
目录
前言
跟随英雄算法联盟博主—英雄哪里出来,每天完成相应的算法练习,一个月后,必定会有所成长!
一、1838.最高频元素的频数(中等)
1.题目描述
2.解题思路
操作后的最高频元素一定是数组中已有的元素。优先操作距离目标值最近的元素。
遍历数组中的每个元素作为目标值并进行尝试。
3.代码演示(C++)
class Solution
{
public:
int maxFrequency(vector<int>& nums, int k)
{
sort(nums.begin(), nums.end());
int n = nums.size();
long long total = 0;
int l = 0, res = 1;
for (int r = 1; r < n; ++r)
{
total += (long long)(nums[r] - nums[r - 1]) * (r - l);
while (total > k)
{
total -= nums[r] - nums[l];
++l;
}
res = max(res, r - l + 1);
}
return res;
}
};
4.题目链接
二、1590.使数组和能被P整除(中等)
1.题目描述
2.解题思路
假设前缀和sum求出来后,对于n个元素(从1到n),去掉某个区间(t,i]
得到的元素和为sum[n]-(sum[i]-sum[t]);如果这个数能整除P,那么
sum[i]-sum[n]必须和sum[t]模P同余数,只要枚举i,sum[i]-sum[n]
就变成了常量,sum[t]可以在扫描后插入哈希表中,因此变成在哈希表
中寻找sum[i]-sum[n]。任何数都要模P,负数需要加上P,找到区间最
小的(t,i]即可。
3.代码演示(C++)
class Solution
{
#define maxx 1000000000
public:
int minSubarray(vector<int>& nums, int p)
{
int i;
int n = nums.size();
int sum[100010] = {0};
unordered_map<int, int> hash;
for(i = 1; i <= n; ++i)
{
sum[i] = sum[i-1] + nums[i-1];
sum[i] %= p;
}
if(sum[n] == 0)
{
return 0;
}
int ret = maxx;
hash[ 0 ] = 0;
for(i = 1; i <= n; ++i)
{
int x = (p - sum[n] + sum[i]) % p;
if(hash.find(x) != hash.end())
{
ret = min(ret, i - hash[x]);
}
hash[ sum[i] ] = i;
}
if(ret == maxx || ret == n)
{
ret = -1;
}
return ret;
}
};
4.题目链接
三、1589.所有排列中的最大和(中等)
1.题目描述
2.解题思路
以后再战!
3.代码演示(C++)
4.题目链接
四、1712.将数组分成三个子数组的方案数(中等)
1.题目描述
2.解题思路
下次一定!
3.代码演示(C++)
4.题目链接
总结
每天跟随英雄哥学习相关的算法,一个月会收获很多,如果你想了解更多关于知识星球的内容,欢迎联系我!