【Leetcode】337. House Robber III

题目地址:

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值