作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/



题目地址:https://leetcode.com/problems/house-robber-iii/description/

题目描述

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the “root.” Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that “all houses in this place forms a binary tree”. It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example 1:

     3
/ \
2 3
\ \
3 1
Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.

Example 2:

     3
/ \
4 5
/ \ \
1 3 1
Maximum amount of money the thief can rob = 4 + 5 = 9.

题目大意

从一棵二叉树中取出一些数字,使得取得数字的和最大。取的规则是不能同时取直接相连的两个节点。

解题方法

这个是限定规则下的博弈过程。曾经看过左程云的视频教程,对这个过程印象比较深刻。

本题的做法,就是求本节点+孙子更深节点vs儿子节点+重孙更深的节点的比较。

道理能想明白,代码有点难写。用了dfs函数,虽然递归是自顶向下的,但是因为是不断的return,所以真正求值是从底向上的。用到了一个有两个元素的列表,分别保存了之前层的,不取节点和取节点的情况。然后遍历左右子树,求出当前节点取和不取能得到的值,再返回给上一层。注意这个里面的robcurr是当前节点能达到的最大值,所以最后返回结果的时候试试返回的root节点robcurr的值。

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def dfs(root):
# from bottom to top
if not root: return [0, 0] # before layer, no robcurr, robcurr
robleft = dfs(root.left)
robright = dfs(root.right)
norobcurr = robleft[1] + robright[1]
robcurr = max(root.val + robleft[0] + robright[0], norobcurr)
return [norobcurr, robcurr]
return dfs(root)[1]

二刷的时候换了一种解法,使用的仍然是递归,不过不用返回两个值,而是直接一个值:无论用还是不用情况下,能得到的最好结果。必须使用记忆化递归,否则超时。

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
memo = dict()
return self.helper(root, memo) def helper(self, root, memo):
if not root:
return 0
if root in memo:
return memo[root]
res = 0
notused = self.helper(root.left, memo) + self.helper(root.right, memo)
used = 0
if root.left:
used += self.helper(root.left.left, memo) + self.helper(root.left.right, memo)
if root.right:
used += self.helper(root.right.left, memo) + self.helper(root.right.right, memo)
res = max(notused, used + root.val)
memo[root] = res
return res

三刷的时候,代码思路更简洁明了。递归函数增加一个变量,表示当前节点的父亲节点是否用过。根节点没有父亲节点,所以其父亲节点肯定没用过。然后我们判断在某个节点的父亲用过和没用过的情况下,当前节点能不能用,最优的结果分别是多少。

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
self.d = dict()
return self.helper(root, False) def helper(self, root, parentUsed):
if not root: return 0
if (root, parentUsed) in self.d:
return self.d[(root, parentUsed)]
res = 0
if parentUsed:
res = self.helper(root.left, False) + self.helper(root.right, False)
else:
res = max(root.val + self.helper(root.left, True) + self.helper(root.right, True), self.helper(root.left, False) + self.helper(root.right, False))
self.d[(root, parentUsed)] = res
return res

日期

2018 年 6 月 22 日 —— 这周的糟心事终于完了
2018 年 12 月 25 日 —— 圣诞节快乐
2019 年 3 月 23 日 —— 周末加油鸭

【LeetCode】337. House Robber III 解题报告(Python)的更多相关文章

  1. Leetcode 337. House Robber III

    337. House Robber III Total Accepted: 18475 Total Submissions: 47725 Difficulty: Medium The thief ha ...

  2. [LeetCode] 337. House Robber III 打家劫舍 III

    The thief has found himself a new place for his thievery again. There is only one entrance to this a ...

  3. [LeetCode] 337. House Robber III 打家劫舍之三

    The thief has found himself a new place for his thievery again. There is only one entrance to this a ...

  4. Java [Leetcode 337]House Robber III

    题目描述: The thief has found himself a new place for his thievery again. There is only one entrance to ...

  5. 【LeetCode】62. Unique Paths 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/unique-pa ...

  6. LeetCode 337. House Robber III 动态演示

    每个节点是个房间,数值代表钱.小偷偷里面的钱,不能偷连续的房间,至少要隔一个.问最多能偷多少钱 TreeNode* cur mp[{cur, true}]表示以cur为根的树,最多能偷的钱 mp[{c ...

  7. 【LeetCode】556. Next Greater Element III 解题报告(Python)

    [LeetCode]556. Next Greater Element III 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人 ...

  8. 【LeetCode】376. Wiggle Subsequence 解题报告(Python)

    [LeetCode]376. Wiggle Subsequence 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.c ...

  9. 【LeetCode】649. Dota2 Senate 解题报告(Python)

    [LeetCode]649. Dota2 Senate 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地 ...

随机推荐

  1. Python队列queue模块

    Python中queue模块常用来处理队列相关问题 队列常用于生产者消费者模型,主要功能为提高效率和程序解耦 1. queue模块的基本使用和相关说明 # -*- coding:utf-8 -*- # ...

  2. ui自动化测试,页面方法的使用

    悬浮下拉框 的设置选择 下拉框的选择 显性等待 双击, ActionChains类的方法行动链 提示框 双击,右击 双击用到行动连,提示框用到Alert的类 右击用到的也是行动连 UI自动化测试 #h ...

  3. leetcode刷题之数组NO.4

    1.题目 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数 ...

  4. .NET SAAS 架构与设计 -SqlSugar ORM

    1.数据库设计 常用的Saas分库分为2种类型的库 1.1 基础信息库 主要存组织架构 .权限.字典.用户等 公共信息 性能优化:因为基础信息库是共享的,所以我们可以使用 读写分离,或者二级缓存来进行 ...

  5. Yarn的Tool接口案例

    目录 Yarn的Tool接口案例 Tool接口环境准备 1 新建Maven项目YarnDemo 编写代码 打包jar上传到集群 Yarn的Tool接口案例 Tool接口环境准备 之前写wordcoun ...

  6. 日常Java 2021/10/30

    Java泛型 Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型.泛型的本质是参数化类型,也就是说所操作的数据类型 ...

  7. Redis - 1 - linux中使用docker-compose安装Redis - 更新完毕

    0.前言 有我联系方式的那些半吊子的人私信问我:安装Redis有没有更简单的方式,网上那些文章和视频,没找到满意的方法,所以我搞篇博客出来说明一下我的安装方式吧 1.准备工作 保证自己的linux中已 ...

  8. Spark On Yarn的各种Bug

    今天将代码以Spark On Yarn Cluster的方式提交,遇到了很多很多问题.特地记录一下. 代码通过--master yarn-client提交是没有问题的,但是通过--master yar ...

  9. Hadoop、Hive【LZO压缩配置和使用】

    目录 一.编译 二.相关配置 三.为LZO文件创建索引 四.Hive为LZO文件建立索引 1.hive创建的lzo压缩的分区表 2.给.lzo压缩文件建立索引index 3.读取Lzo文件的注意事项( ...

  10. 转 GSON

    转 https://www.jianshu.com/p/75a50aa0cad1 GSON弥补了JSON的许多不足的地方,在实际应用中更加适用于Java开发.在这里,我们主要讲解的是利用GSON来操作 ...