二维差分+前缀和

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;

}

};

相关推荐
格林威3 分钟前
多相机重叠视场目标关联:解决ID跳变与重复计数的 8 个核心策略,附 OpenCV+Halcon 实战代码!
人工智能·数码相机·opencv·算法·计算机视觉·分类·工业相机
郝学胜-神的一滴5 分钟前
深入理解网络分层模型:数据封包与解包全解析
linux·开发语言·网络·程序人生·算法
永远都不秃头的程序员(互关)5 分钟前
【K-Means深度探索(九)】K-Means与数据预处理:特征缩放与降维的重要性!
算法·机器学习·kmeans
源代码•宸10 分钟前
Golang原理剖析(逃逸分析)
经验分享·后端·算法·面试·golang··内存逃逸
重生之后端学习17 分钟前
25. K 个一组翻转链表
java·数据结构·算法·leetcode·职场和发展
CoderCodingNo24 分钟前
【GESP】C++五级练习题 luogu-P2242 公路维修问题
开发语言·c++·算法
不知名XL31 分钟前
day30 动态规划03
算法·动态规划
张祥64228890431 分钟前
线性代数本质笔记十二
人工智能·算法·机器学习
程序员-King.32 分钟前
day157—回溯—括号生成(LeetCode-22)
算法·leetcode·回溯
Σίσυφος190038 分钟前
视觉矩阵 之 单应矩阵
人工智能·算法·矩阵