lc1838
排序+前缀和+滑窗
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<long long> p(n + 1, 0);
for (int i = 1; i <= n; i++) {
p[i] = p[i - 1] + nums[i - 1];
}
int ret = 1;
int left = 0;
for (int right = 1; right < n; right++) {
++while ((right - left + 1) * nums[right] - (p[right + 1] - p[left]) > k) {++
++left++;++
}
++ret = max(ret, right - left + 1);++
}
return ret;
}
};
lc1894
ll sum不能用reduce会溢出,要手动模拟一下..
class Solution {
/*
输入:chalk = [5,1,5], k = 22
输出:0
*/
public:
int chalkReplacer(vector<int>& chalk, int k)
{
long long sum=0;
for(auto& c:chalk) sum+=c;
if(sum<k)
k%=(int)sum;
int ret=0,n=chalk.size();
for(int i=0;i<n;i++)
{
if(k-chalk[i]<0) return i;
else k-=chalk[i];
}
return 0;
}
};
lc2536
二维差分数组+前缀和
完成多个子矩阵的元素加1操作
++初始化差分数组d,大小为(n+2)×(n+2)(防止越界)++
1-n 通过d cal mat
// 二维前缀和公式
d++[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];++
++mat[i - 1][j - 1] = d[i][j];++
我们需要对多个子矩阵执行"每个元素加1"的操作,直接遍历每个子矩阵的所有元素会导致时间复杂度过高。++差分数组可以将区间加操作的时间复杂度优化到O(1),之后再通过前缀和计算得到最终矩阵。++
class Solution {
public:
vector<vector<int>> rangeAddQueries(int n, vector<vector<int>>& queries)
{
// ++初始化差分数组d,大小为(n+2)×(n+2)(防止越界)++
vector<vector<int>> d(n + 2, vector<int>(n + 2, 0));
for (auto& q : queries) {
int i1 = q[0], j1 = q[1], i2 = q[2], j2 = q[3];
// 差分的区间更新操作
d[i1 + 1][j1 + 1]++;
d[i1 + 1][j2 + 2]--;
d[i2 + 2][j1 + 1]--;
d[i2 + 2][j2 + 2]++;
}
// 初始化结果矩阵mat,大小为n×n
vector<vector<int>> mat(n, vector<int>(n, 0));
// 计算二维前缀和,得到最终矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// 二维前缀和公式
d++[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];++
++mat[i - 1][j - 1] = d[i][j];++
}
}
return mat;
}
};
说明
-
差分数组初始化:创建 (n+2)×(n+2) 的差分数组 d ,防止边界越界。
-
差分数组更新:对于每个查询 [row1, col1, row2, col2] ,通过++修改差分数组的四个关键点,标记"该区间需要加1"。++
-
二维前缀和计算:通过++遍历差分数组并计算二维前缀和,得到每个位置的最终值++,存入结果矩阵 mat 中。
时间复杂度为 O(n² + m) (其中 m 是查询次数),能够高效处理题目中的输入规模~
lc1029
diff sort贪心,先满足a b diff大的取最优
class Solution {
public:
int twoCitySchedCost(vector<vector<int>>& costs)
{
int n=costs.size();
vector<pair<int,int>> diff;
for(int i=0;i<n;i++)
{
vector<int> c=costs[i];
diff.push_back({abs(c[0]-c[1]),i});
}
sort(diff.rbegin(),diff.rend());
int a=n/2,b=n/2,ret=0;
for(int i=0;i<n;i++)
{
int idx=diff[i].second;
int x=costs[idx][0],y=costs[idx][1];
if(!a)
{
ret+=y;b--;
continue;
}
if(!b)
{
ret+=x;a--;
continue;
}
if(x<y)
{
ret+=x;a--;
}
else if(x>y)
{
ret+=y;b--;
}
else
{
if(a>b) a--;
else b--;
ret+=x;
}
}
return ret;
}
};
lc1090
value降序
hash记录labelCount[l] < useLimit实现限制
class Solution {
public:
int largestValsFromLabels(vector<int>& values, vector<int>& labels, int numWanted, int useLimit)
{
vector<pair<int, int>> valLabel;
int n = values.size();
for (int i = 0; i < n; i++) {
valLabel.emplace_back(values[i], labels[i]);
}
sort(valLabel.rbegin(), valLabel.rend());
unordered_map<int, int> labelCount; // 每个标签已使用的次数
vector<int> selected;
int ret=0,cnt=0;
for (auto& [v,l]: valLabel) {
if (labelCount[l] < useLimit && cnt < numWanted) {
ret+=v;
cnt++;
labelCount[l]++;
}
}
return ret;
}
};