持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 851. 喧闹和富有 】- JavaScript(记忆化DFS)
题目描述
有一组 n 个人作为实验对象,从 0 到 n - 1 编号,其中每个人都有不同数目的钱,以及不同程度的安静值(quietness)。为了方便起见,我们将编号为 x 的人简称为 "person x "。
给你一个数组 richer ,其中 richer[i] = [ai, bi] 表示 person ai 比 person bi 更有钱。另给你一个整数数组 quiet ,其中 quiet[i] 是 person i 的安静值。richer 中所给出的数据 逻辑自洽(也就是说,在 person x 比 person y 更有钱的同时,不会出现 person y 比 person x 更有钱的情况 )。
现在,返回一个整数数组 answer 作为答案,其中 answer[x] = y 的前提是,在所有拥有的钱肯定不少于 person x 的人中,person y 是最安静的人(也就是安静值 quiet[y] 最小的人)。
示例 1:
输入:richer = [[1,0],[2,1],[3,1],[3,7],[4,3],[5,3],[6,3]], quiet = [3,2,5,4,6,1,7,0] 输出:[5,5,2,5,4,5,6,7]
记忆化DFS
思路分析:
通过使用一个邻接表来表示比该位更有钱的人,然后用DFS来找,在寻找过程中不断更新最安静的人及其安静值,不断地深入总会找到一个可能最有钱的人,此时最安静的人就是一路照下来最安静的人,即该处的答案,这时把答案通过map来进行记录在字典里以备以后使用。比如一开始1->3->6->7找到了7,第二次如果是2->4->1,因为此时1的答案已经记录过了,可以直接返回该人后面最安静的人,避免后面的所有操作。实现步骤:
- 为每个人创建一个对象
- 搭桥,用于给偏穷的人指向偏富裕的人
- 如果不存在比当前人物富裕的,直接返回本人索引
- 如果已经计算过了,则直接返回
- 先给自己放入next,用于和其他人比较
- 查找比自己有钱的人的安静值,取最小的放入next
var loudAndRich = function(richer, quiet) {
const map = {};
for (let i = 0; i < richer.length; i++) {
const array = map[richer[i][0]] || [];
array.push(richer[i][1]);
map[richer[i][0]] = array;
}
const answer = [];
for (let i = 0; i < quiet.length; i++) {
answer.push(i);
}
const recursion = (richer, poorer)=>{
if (quiet[richer] < quiet[poorer]) {
answer[poorer] = richer;
quiet[poorer] = quiet[richer];
const array = map[poorer];
if (!array) return;
for (let i = 0; i < array.length; i++) {
recursion(richer, array[i]);
}
};
};
for (let i = 0; i < richer.length; i++) {
recursion(richer[i][0], richer[i][1]);
}
return answer;
};
注意:这道题目直接用lru_cache记忆化在某个样例有bug,没发现什么原因。以及题目给的例子感觉有些有点问题,下面给定的richer数组里没有比2更有钱的,为什么在输出里,2的位置是1的安静值2,意思就是1比2有钱,这和richer里的2比1有钱 矛盾了。
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤