预hash|vector<int> dfs

lc3429

for(int i=1;i<mem.size();i++) //check

if(memi!=mem0) f=false;

++return cnt; //返回子树个数和++

class Solution {

/*

如果一个节点的所有子节点为根的 子树 包含的节点数相同,则认为该节点是一个 好节点。

*/

public:

int countGoodNodes(vector<vector<int>>& edges)

{

int n=edges.size()+1;

vector<vector<int>> g(n);

for(auto& e:edges)

{

ge\[0].push_back(e1);

ge\[1].push_back(e0);

}

int ret=0;

auto dfs=\&(this auto&& dfs,int p,int fa)->int

{

int cnt=1;

vector<int> mem;

bool f=true;

for(auto& e:gp)

{

if(e!=fa)

{

int sub=dfs(e,p);

mem.push_back(sub);

cnt+=sub;

}

}

for(int i=1;i<mem.size();i++)

++if(memi!=mem0) f=false;++

if(f) ret++;

++return cnt; //返回子树个数和++

};

dfs(0,-1);

return ret;

}

};

lc1530

DFS遍历树,++vector<int> dfs ++返回子++树中所有叶子到自己的距离++,统计左右子树叶子距离和≤目标值的对数,累加得到结果

trick

/++/ 统计左右子树叶子的合法对++

++for(int x:l) for(int y:r) if(x+y <= distance) ret++;++

class Solution

{

public:

int countPairs(TreeNode* root, int distance)

{

int ret=0;

auto dfs=\&(this auto&& dfs,TreeNode* node)->vector<int>

{

if(!node) return {};

if(!node->left && !node->right) return {1}; // 叶子节点,深度1

auto l=dfs(node->left), r=dfs(node->right);

/++/ 统计左右子树叶子的合法对++

++for(int x:l) for(int y:r) if(x+y <= distance) ret++;++

// 深度+1后返回

vector<int> res;

for(int x:l) res.push_back(x+1);

++for(int x:r) res.push_back(x+1);++

return res;

};

dfs(root);

return ret;

}

};

lc2439

将大的数'匀'给前面小的数,求最终数组的最大值的最小值

取决于前缀和的平均值上取整"的最大值------因为前面的数无法"转移"到后面,只能++让后面的大数向前匀++(比如第i位的数只能影响前i位)

int minimizeArrayValue(vector<int>& nums)

{

int n=nums.size();

vector<long long> p(n+1);

for(int i=1;i<=n;i++)

pi=pi-1+numsi-1;

int ret=0;

for(int i=1;i<=n;i++)

{

++ret=max(ret,(int)((pi+i-1)/i));++

}

return ret;

}

思路:

  1. 遍历数组,维护前缀和sum(前i+1个数的总和);

  2. 对于每个位置i,计算前i+1个数的平均值的上取整

  3. 所有位置的这个"平均值上取整"的最大值,就是答案。

举个例子(输入3,7,1,6):

  • 前1位:sum=3 → 3/1=3

  • 前2位:sum=10 → 10/2=5

  • 前3位:sum=11 → 11/3≈3.67 → 上取整4

  • 前4位:sum=17 → 17/4≈4.25 → 上取整5

这些值的最大值是5,就是答案

lc2261

class Solution {

/*

输入:cards = 3,4,2,3,4,7

输出:4

*/

public:

int minimumCardPickup(vector<int>& cards) {

unordered_map<int,vector<int>> hash;

int ret=INT_MAX;

for(int i=0;i<(int)cards.size();i++)

{

hashcards\[i].push_back(i);

}

for(auto& _,b:hash)

{

int n=b.size();

for(int i=1;i<n;i++)

{

ret=min(ret,bi-bi-1+1);

}

}

return ret==INT_MAX?-1:ret;

}

};

lc2813

hash预处理

窗口内需要删除的元素数 = arrright - arrleft - (right - left) (总长度 - 有效元素数)

"删除最多k个元素后,得到最长的等值子数组"

统计每个数字的位置,用滑动窗口计算最大长度

class Solution {

public:

int longestEqualSubarray(vector<int>& nums, int k)

{

int n = nums.size();

int ret = 0;

// 统计每个数字对应的所有位置

unordered_map<int, vector<int>> pos;

for (int i = 0; i < n; ++i) {

posnums\[i].push_back(i);

}

// 对每个数字的位置数组,用滑动窗口计算最大长度

for (auto& _, arr : pos) {

int left = 0;

for (int right = 0; right < arr.size(); ++right) {//try right结尾的 max ret

// 窗口内需要删除的元素数 = 当前位置 - 窗口左位置 - (right - left)

while (arrright - arrleft - (right - left) > k)

left++;

++ret = max(ret, right - left + 1);++

}

}

return ret;

}

};

  1. 用哈希表记录每个数字出现的所有位置;

  2. 对每个数字的位置数组,用++滑动窗口维护"删除不超过k个元素"的区间:++

  • ++窗口内需要删除的元素数 = arrright - arrleft - (right - left) (总长度 - 有效元素数);++

  • 若删除数超过k,则左指针右移;

  • 窗口长度( right-left+1 )即为当前数字的最大等值子数组长度。

这样就能高效求出删除最多k个元素后的最长等值子数组长度。

相关推荐
To_OC4 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
2401_841495644 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
爱刷碗的苏泓舒8 小时前
PPP-AR 中的参考星选取:数学原理、评价指标与切换处理
算法·gnss·模糊度固定·ppp-ar·星间单差·参考星·卫星端偏差
烬羽11 小时前
递归老写崩?一个"退回"公式,把回溯题变成填空题
javascript·深度学习·算法
闪电悠米11 小时前
力扣hot100-41.缺失的第一个正数-原地哈希详解
数据结构·算法·哈希算法
星空露珠12 小时前
28种颜色对应名称,
开发语言·数据库·算法·游戏·lua
QXWZ_IA14 小时前
桥梁数字孪生怎么落地?
人工智能·科技·算法·智能硬件·政务
Kel14 小时前
输出层与反分词(Output Layer & Detokenization)
人工智能·算法·架构
陕西企来客14 小时前
2026年7月技术好GEO优化方案:算法适配与内容策略
人工智能·算法·机器学习·技术好geo优化