预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个元素后的最长等值子数组长度。

相关推荐
AI小老六2 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术2 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize3 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考16 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队20 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC2 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
_清歌2 天前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法