P48-打家劫舍3-二叉树-动态规划
//打家劫舍3--二叉树 /* * 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口 * 我们称之为“根”。除了“根”之外,每栋房子有且只有一个“父”房子与之相连。一番侦察之后,聪明的小偷意思到 * “这个地方的所有房屋的排列类似于一棵二叉树”。如果两个直接相连的房子在用一天晚上被打劫,房屋将自动报警 * */ public class P48 { public static void main(String[] args) { /* * 3 * / \ * 2 3 * / \ * 3 1 * 最大值7 * */ TreeNode node5 = new TreeNode(1, null, null); TreeNode node4 = new TreeNode(3, null, null); TreeNode node3 = new TreeNode(3, null, node5); TreeNode node2 = new TreeNode(2, node4, null); TreeNode node1 = new TreeNode(3, node2, node3); int[] i = dfs(node1); System.out.println(Math.max(i[0], i[1])); } //深度优先 public static int[] dfs(TreeNode node){ //int[]{select最优解,notselect最优解},保存选与不选的最优解 if(node == null){ //递归到叶子节点的孩子 return new int[]{0, 0}; } int[] l = dfs(node.left); int[] r = dfs(node.right); //如果是选中当前node,则node.left是不能选的,node.right也是不能选 //l[1]就是不选的时候的最优解,r[1]也是不选的时候的最优解 int select = node.val + l[1] + r[1]; int notSelect = Math.max(l[0], l[1]) + Math.max(r[0], r[1]); //不确定偷不偷,判断大小 return new int[]{select, notSelect}; } static class TreeNode{ int val; TreeNode left; TreeNode right; TreeNode(){} TreeNode(int val){ this.val = val; } TreeNode(int val, TreeNode left, TreeNode right){ this.val = val; this.left = left; this.right = right; } } }