二维差分+前缀和

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;

}

};

说明

  1. 差分数组初始化:创建 (n+2)×(n+2) 的差分数组 d ,防止边界越界。

  2. 差分数组更新:对于每个查询 [row1, col1, row2, col2] ,通过++修改差分数组的四个关键点,标记"该区间需要加1"。++

  3. 二维前缀和计算:通过++遍历差分数组并计算二维前缀和,得到每个位置的最终值++,存入结果矩阵 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;

}

};

相关推荐
长安er3 小时前
LeetCode215/347/295 堆相关理论与题目
java·数据结构·算法·leetcode·
元亓亓亓3 小时前
LeetCode热题100--62. 不同路径--中等
算法·leetcode·职场和发展
小白菜又菜4 小时前
Leetcode 1925. Count Square Sum Triples
算法·leetcode
登山人在路上5 小时前
Nginx三种会话保持算法对比
算法·哈希算法·散列表
写代码的小球5 小时前
C++计算器(学生版)
c++·算法
AI科技星5 小时前
张祥前统一场论宇宙大统一方程的求导验证
服务器·人工智能·科技·线性代数·算法·生活
Fuly10246 小时前
大模型剪枝(Pruning)技术简介
算法·机器学习·剪枝
Xの哲學6 小时前
Linux网卡注册流程深度解析: 从硬件探测到网络栈
linux·服务器·网络·算法·边缘计算
bubiyoushang8886 小时前
二维地质模型的表面重力值和重力异常计算
算法
仙俊红6 小时前
LeetCode322零钱兑换
算法