后序遍历的优秀例题——851. 喧闹和富有
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后序遍历的优秀例题——851. 喧闹和富有相关的知识,希望对你有一定的参考价值。
题目
题目解析
这题实际上就是一个图的遍历,以下是输入示例对应的图形:
由于我们需要找到比某个编号有钱且安静值最小的,根据图形我们可以看出,在 0 结点之下的根节点都要比 0 有钱,我们只需要通过 dfs 遍历这颗树即可更新答案,但是会出现一个问题:如果使用的是前序的遍历则需要增加很多变量进行记录状态,且无法对这一次遍历走过的路径进行更新。
如何解决?
使用后序遍历即可,因为后序则相当于直接算出了所有子树的答案,然后再更新根节点,这样做正好符合本题的遍历思路。
解题代码
前序+记录
如果直接使用前序遍历进行答案更新,则需要每次遍历的时候把整个路径都搜索一遍,且需要一个变量贯穿始终来进行答案的更新!这里C++直接用左值引用即可。
为了防止太过暴力而超时,用check数组对每一次更新搜索过程进行状态记录,防止重复遍历。
解题代码:
class Solution
public:
vector<int> loudAndRich(vector<vector<int>>& richer, vector<int>& quiet)
int n = quiet.size();
vector<int> record[n];
for(int i=0;i<richer.size();i++)
record[richer[i][1]].emplace_back(richer[i][0]);
bool check[n];
function<void(pair<int,int>&,int)> dfs = [&](pair<int,int>& ret,int next)
for(auto t:record[next])
if(ret.first>quiet[t])
ret.first = quiet[t];
ret.second = t;
if(!check[t])
check[t] = 1;
dfs(ret,t);
;
vector<int>ret(n);
for(int i=0;i<n;i++)
pair<int,int>reINT_MAX,i;
memset(check,0,sizeof(check));
dfs(re,i);
ret[i] = quiet[i]<re.first?i:re.second;
return ret;
;
后序遍历
由于根据题意,实际上后序遍历的顺序,正好符合题目的遍历先后依赖!直接后序即可。
解题代码:
class Solution
public:
vector<int> loudAndRich(vector<vector<int>> &richer, vector<int> &quiet)
int n = quiet.size();
vector<vector<int>> g(n);
for (auto &r : richer)
g[r[1]].emplace_back(r[0]);
vector<int> ans(n, -1);
function<void(int)> dfs = [&](int x)
if (ans[x] != -1)
return;
ans[x] = x;
for (int y : g[x])
dfs(y);
if (quiet[ans[y]] < quiet[ans[x]])
ans[x] = ans[y];
;
for (int i = 0; i < n; ++i)
dfs(i);
return ans;
;
以上是关于后序遍历的优秀例题——851. 喧闹和富有的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 851 喧闹和富有[dfs] HERODING的LeetCode之路
LeetCode 807. 保持城市天际线 / 630. 课程表 III(贪心+优先队列)/ 851. 喧闹和富有(拓扑排序)