力扣题目
解题思路
java代码
力扣题目:
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root
。
除了 root
之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。
给定二叉树的 root
。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。
示例 1:
输入: root = [3,2,3,null,3,null,1] 输出: 7 解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7
示例 2:
输入: root = [3,4,5,1,3,null,1] 输出: 9 解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9
提示:
- 树的节点数在
[1, 104]
范围内 0 <= Node.val <= 104
解题思路:
在一个给定的二叉树中,找到从根节点到叶子节点的路径上,能够偷取的最大金额的问题。
使用深度优先搜索算法(DFS)进行递归求解,通过动态规划的方式计算每个节点的最大金额。在每个节点处,可以选择偷取该节点的金额或者不偷取,但不能同时偷取父节点和子节点的金额。返回从根节点到叶子节点的路径上能够偷取的最大金额。
函数rob调用dfs函数来计算每个节点的最大金额,并返回根节点处的最大金额。dfs函数返回一个Pair对象,其中getKey()表示不偷取当前节点的金额,getValue()表示偷取当前节点的金额。在递归过程中,对于每个节点,先递归计算其左子树和右子树的最大金额,然后根据当前节点是否被偷取,计算出当前节点的最大金额。最后,将当前节点的最大金额作为结果返回。
java代码:
package org.example;
import javafx.util.Pair;
import javax.swing.tree.TreeNode;
public class Leetcode337 {
public static int rob(TreeNode root) {
Pair<Integer, Integer> dp = dfs(root);
return Math.max(dp.getKey(), dp.getValue());
}
private static Pair<Integer, Integer> dfs(TreeNode root) {
if(root == null) {
return new Pair<>(0, 0);
}
Pair<Integer, Integer> dpLeft = dfs(root.left);
Pair<Integer, Integer> dpRight = dfs(root.right);
int val1 = Math.max(dpLeft.getKey(), dpLeft.getValue()) +
Math.max(dpRight.getValue(), dpRight.getKey());//不偷
int val2 = dpLeft.getKey() + dpRight.getKey() + root.val;
return new Pair<>(val1, val2);
}
public static void main(String[] args) {
// 测试代码示例
TreeNode root = new TreeNode(3);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.right = new TreeNode(3);
root.right.right = new TreeNode(1);
int result = rob(root);
System.out.println(result); // 输出计算结果
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}