【Leetcode】337. House Robber III

tech2025-04-01  1

题目地址:

https://leetcode.com/problems/house-robber-iii/

给定一个二叉树,要求在其中选取若干数使得和最大,但相邻的两个节点的数不能同时选。

思路是动态规划。设 x x x表示树根, l l l表示左子树, r r r表示右子树, f [ x ] [ 0 ] f[x][0] f[x][0]表示当不选 x x x的时候,从 x x x为树根的这棵树上能选数的最大和; f [ x ] [ 1 ] f[x][1] f[x][1]表示当选 x x x的时候,从 x x x为树根的这棵树上能选数的最大和。则: f [ x ] [ 0 ] = max ⁡ { f [ l ] [ 0 ] , f [ l ] [ 1 ] } + max ⁡ { f [ r ] [ 0 ] , f [ r ] [ 1 ] } f [ x ] [ 1 ] = x + f [ l ] [ 0 ] + f [ r ] [ 0 ] f[x][0]=\max\{f[l][0],f[l][1]\}+\max\{f[r][0],f[r][1]\}\\f[x][1]=x+f[l][0]+f[r][0] f[x][0]=max{f[l][0],f[l][1]}+max{f[r][0],f[r][1]}f[x][1]=x+f[l][0]+f[r][0]答案就是 max ⁡ { f [ x ] [ 0 ] , f [ x ] [ 1 ] } \max\{f[x][0],f[x][1]\} max{f[x][0],f[x][1]}。一遍DFS即可。代码如下:

public class Solution { public int rob(TreeNode root) { if (root == null) { return 0; } int[] dp = dfs(root); return Math.max(dp[0], dp[1]); } private int[] dfs(TreeNode root) { if (root == null) { return new int[]{0, 0}; } int[] dp = new int[2]; int[] left = dfs(root.left), right = dfs(root.right); dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]); dp[1] = root.val + left[0] + right[0]; return dp; } } class TreeNode { int val; TreeNode left, right; public TreeNode(int val) { this.val = val; } }

时间复杂度 O ( n ) O(n) O(n),空间 O ( h ) O(h) O(h)

最新回复(0)