预hash|vector<int> dfs

lc3429

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

if(mem[i]!=mem[0]) 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)

{

g[e[0]].push_back(e[1]);

g[e[1]].push_back(e[0]);

}

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:g[p])

{

if(e!=fa)

{

int sub=dfs(e,p);

mem.push_back(sub);

cnt+=sub;

}

}

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

++if(mem[i]!=mem[0]) 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++)

p[i]=p[i-1]+nums[i-1];

int ret=0;

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

{

++ret=max(ret,(int)((p[i]+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++)

{

hash[cards[i]].push_back(i);

}

for(auto& [_,b]:hash)

{

int n=b.size();

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

{

ret=min(ret,b[i]-b[i-1]+1);

}

}

return ret==INT_MAX?-1:ret;

}

};

lc2813

hash预处理

窗口内需要删除的元素数 = arr[right] - arr[left] - (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) {

pos[nums[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 (arr[right] - arr[left] - (right - left) > k)

left++;

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

}

}

return ret;

}

};

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

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

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

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

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

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

相关推荐
你撅嘴真丑7 小时前
第九章-数字三角形
算法
uesowys7 小时前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
ValhallaCoder7 小时前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮7 小时前
AI 视觉连载1:像素
算法
智驱力人工智能7 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥8 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风8 小时前
代码随想录第十五天
数据结构·算法·leetcode
XX風8 小时前
8.1 PFH&&FPFH
图像处理·算法
NEXT069 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
代码游侠9 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法