337. 打家劫舍 III

这是一篇关于解决LeetCode上的《House Robber III》问题的博客。问题描述了一个小偷试图在二叉树结构的房屋中盗窃,但相邻房屋在同一晚上会被报警。文章通过动态规划的方法,利用深度优先搜索(DFS)策略来计算每个节点被选中或不选中所能获得的最大金额,并最终返回整个树中能偷得的最高金额。示例和思路解析帮助理解问题的解决过程。

地址:

力扣icon-default.png?t=M1L8https://leetcode-cn.com/problems/house-robber-iii/

题目:

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。

示例 1:

输入: root = [3,2,3,null,3,null,1]
输出: 7 
解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7

示例 2:

输入: root = [3,4,5,1,3,null,1]
输出: 9
解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9
 

提示:

树的节点数在 [1, 104] 范围内
0 <= Node.val <= 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

一开始没有细读,以为就是看奇数层,偶数层选择问题,于是就借用二叉树的层序遍历处理

结果发现不对,比如:

 再来考虑我们之前的打家劫舍,能够确定一个初始点,然后推到到最后

但是目前来看,这个初始点不好找,每个节点都可能是初始点,没有唯一性

二叉树能够确定唯一的只有 叶子 节点,我们来看叶子节点的情况:

 叶子节点左右子节点 = 0,这个确定了

我们对于每个节点都有两种可能:选 或者 不选

从叶子节点来看:

1. 选定根节点 4,加上左子节点的不选,加上右子节点的不选

2. 不选根节点,加上

        2.1 左子节点 选中,不选中 的最大值

        2.2 右子节点 选中,不选中 的最大值

        两者相加

1,2 组合就得到了 节点 4 选中,不选中的值

再回溯就能得到 root 节点 选中,不选中的值,取最大值即可

方法一、动态规划

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int *dfs(struct TreeNode* root)
{
	int *money = (int *)malloc(sizeof(int) * 2);
	if(root == NULL)
	{
		money[0] = 0;
		money[1] = 0;
		
		return money;
	}
	
	int *left = dfs(root->left);
	int *right = dfs(root->right);
	
	money[0] = root->val + left[1] + right[1];
	money[1] = fmax(left[0], left[1]) + fmax(right[0], right[1]);
	free(left);
	free(right);
	
	return money;
}
 
int rob(struct TreeNode* root){	
	int *money = (int *)malloc(sizeof(int) * 2);
	money = dfs(root);
	
	int select = money[0];
	int notselect = money[1];
	
	free(money);
	return fmax(select, notselect);
}

查看更多刷题笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值