携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情
前言
- leetcode hot100,是大厂面试高频题,也是必刷算法题。精选了100道LeetCode上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,按照官方说的,熟练掌握这 100 道题,就具备了代码世界通行的基本能力。
leetcode337题(打家劫舍 III)
本文来讲hot100第337题( 打家劫舍 III),本题是树结构的动态规划题目。需要了解树的几种遍历方式,还需要对动态规划有了解。
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。
除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。
给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。
示例:
输入: root = [3,2,3,null,3,null,1]
输出: 7
解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7
输入: root = [3,4,5,1,3,null,1]
输出: 9
解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9
提示:
- 树的节点数在
[1, 104]范围内 0 <= Node.val <= 104
分析
- 房子排列是二叉树
- 不可选相连的2个房子,也就是有父子关系的节点
- 求最高金额,就是求选择的节点的和最大
- 本题是树型的动态规划题目,需要对树的遍历方式足够了解
思路
- 我们使用状态转移容器来记录状态的变化,
- 这里使用一个数组,记录当前节点偷与不偷所得到的的最大金钱。
- 首先明确的是使用后序遍历。 因为通过递归函数的返回值来做下一步计算。
- 通过递归左节点,得到左节点偷与不偷的金钱。
- 通过递归右节点,得到右节点偷与不偷的金钱
代码
const postOrder = (node) => {
// 递归出口
if (!node) return [0, 0];
// 遍历左子树
const left = postOrder(node.left);
// 遍历右子树
const right = postOrder(node.right);
// 不偷当前节点,左右子节点都可以偷或不偷,取最大值
const DoNot = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
// 偷当前节点,左右子节点只能不偷
const Do = node.val + left[0] + right[0];
// [不偷,偷]
return [DoNot, Do];
};
const res = postOrder(root);
// 返回最大值
return Math.max(...res);
结语
- 本题是树结构的动态规划题目。理解了题目,核心在于选或不选,我们需要了解树的几种遍历方式,层序遍历,前序遍历,中序遍历,后序遍历,还需要对动态规划有了解。