选择:抢还是不抢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int rob (int [] nums) { int n = nums.length; int dp_i_1 = 0 , dp_i_2 = 0 ; int dp_i = 0 ; for (int i = n - 1 ; i >= 0 ; i--) { dp_i = Math.max(dp_i_1, nums[i] + dp_i_2); dp_i_2 = dp_i_1; dp_i_1 = dp_i; } return dp_i; } }
分别判断两种情况谁收益更高:取头或取尾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int rob(int[] nums) { int n = nums.length; if (n == 1) { return nums[0]; } return Math.max(robRange(nums, 0, n - 2), robRange(nums, 1, n - 1)); } private int robRange(int[] nums, int start, int end) { int n = nums.length; int dp_i_1 = 0, dp_i_2 = 0; int dp_i = 0; for (int i = end; i >= start; i--) { dp_i = Math.max(dp_i_1, dp_i_2 + nums[i]); dp_i_2 = dp_i_1; dp_i_1 = dp_i; } return dp_i; } }
1 2 3 4 5 6 7 8 9 10 class Solution { public int rob (TreeNode root) { if (root == null ) return 0 ; int val1 = root.val; if (root.left != null ) val1 += rob(root.left.left) + rob(root.left.right); if (root.right != null ) val1 += rob(root.right.left) + rob(root.right.right); int val2 = rob(root.left) + rob(root.right); return Math.max(val1, val2); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { private Map<TreeNode, Integer> map = new HashMap<>(); public int rob (TreeNode root) { if (root == null ) { return 0 ; } if (map.containsKey(root)) { return map.get(root); } int do_it = root.val + (root.left == null ? 0 : rob(root.left.left) + rob(root.left.right)) + (root.right == null ? 0 : rob(root.right.left) + rob(root.right.right)); int not_do = rob(root.left) + rob(root.right); int res = Math.max(do_it, not_do); map.put(root, res); return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int rob (TreeNode root) { int [] res = dp(root); return Math.max(res[0 ], res[1 ]); } private int [] dp(TreeNode root) { if (root == null ) { return new int []{0 , 0 }; } int [] left = dp(root.left); int [] right = dp(root.right); int do_it =root.val + left[0 ] + right[0 ]; int not_do = Math.max(left[0 ], left[1 ]) + Math.max(right[0 ], right[1 ]); return new int []{not_do,do_it}; } }
总结 关键就是选择 偷或者不偷,因为只是相邻的不能偷,所以需要记录的是最近两个状态。