tree 337_979

337. House Robber III

一个小偷进入一个小区偷东西,小区是一个二叉树,只有一个入口,即root,不能偷任何相邻的两个房子,每个房子可以偷的金钱不一,要求偷的金额最大。

  1. 后序遍历每个结点,获取当前结点左子树的结果和右子树的结果,进行相加获得sum1
  2. 当前结点如果存在左右子结点,就获取它左孩子的左右子树的结果之和,右孩子的左右子树的结果之和,将他们相加再与该结点值相加获得sum2
  3. 比较sum1和sum2,将较大值作为以当前结点为根结点的结果进行返回
  4. 但是这样会很慢,因为有很多的重复计算
  5. 通过一个hashmap记录每个结点的结果进行优化,每遍历到一个结点时看看hashmap是是否有当前结点的结果,有就直接使用,没有就执行上面的步骤,并将结果添加到hashmap中
public int rob(TreeNode root) {
    if (root == null) return 0;

    HashMap<TreeNode, Integer> map = new HashMap<>();
    return helper(root, map);
}

public int helper(TreeNode root, HashMap<TreeNode, Integer> map) {
    if (root == null) return 0;
    if (map.containsKey(root)) return map.get(root);

    int sum = 0;
    if (root.left != null) {
        sum += helper(root.left.left, map) + helper(root.left.right, map);
    }
    if (root.right != null) {
        sum += helper(root.right.left, map) + helper(root.right.right, map);
    }

    int res = Math.max(sum + root.val, helper(root.left, map) + helper(root.right, map));
    map.put(root, res);
    return res;
}

979. Distribute Coins in Binary Tree

给一个二叉树,共有n个结点,每个结点都有大于等于0个硬币,总共有n个硬币,将硬币从一个结点移动到另一个结点上算一步,求最小需要多少步可以将硬币移动到所有结点上(即每个结点上都有且只有一个硬币。)

将二叉树看作有一个根结点和一个左子树和一个右子树这样三个部分,那么总共移动的步数就是:根结点硬币数-1 + 左子树移动的步数 + 右子树移动的步数 的绝对值:
在这里插入图片描述

int res = 0;
public int distributeCoins(TreeNode root) {
    helper(root);
    return res;
}

public int helper(TreeNode root) {
    if (root == null) return 0;

    int val = root.val-1 + helper(root.left) + helper(root.right);
    res += Math.abs(val);
    return val;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值