337. House Robber III
Вор снова нашел себе новое место для краж. В этом районе есть только один вход, который называется корнем.
Кроме корня, каждый дом имеет только один родительский дом. После осмотра, умный вор понял, что все дома в этом месте образуют бинарное дерево. Полиция будет автоматически уведомлена, если два дома, напрямую связанные между собой, будут ограблены в одну ночь.
Дано корневое дерево бинарного дерева, верните максимальную сумму денег, которую вор может украсть, не уведомляя полицию.
Пример:
Input: root = [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
C# решение
сопоставлено/оригиналpublic class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution {
public int Rob(TreeNode root) {
var answer = Helper(root);
return Math.Max(answer[0], answer[1]);
}
private int[] Helper(TreeNode node) {
if (node == null) return new int[] { 0, 0 };
var left = Helper(node.left);
var right = Helper(node.right);
int rob = node.val + left[1] + right[1];
int notRob = Math.Max(left[0], left[1]) + Math.Max(right[0], right[1]);
return new int[] { rob, notRob };
}
}
C++ решение
auto-draft, проверить перед отправкой#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
class Solution {
public:
public int Rob(TreeNode root) {
var answer = Helper(root);
return max(answer[0], answer[1]);
}
private vector<int>& Helper(TreeNode node) {
if (node == null) return new int[] { 0, 0 };
var left = Helper(node.left);
var right = Helper(node.right);
int rob = node.val + left[1] + right[1];
int notRob = max(left[0], left[1]) + max(right[0], right[1]);
return new int[] { rob, notRob };
}
}
Java решение
сопоставлено/оригиналclass Solution {
public int[] helper(TreeNode node) {
if (node == null) {
return new int[] { 0, 0 };
}
int left[] = helper(node.left);
int right[] = helper(node.right);
int rob = node.val + left[1] + right[1];
int notRob = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
return new int[] { rob, notRob };
}
public int rob(TreeNode root) {
int[] answer = helper(root);
return Math.max(answer[0], answer[1]);
}
}
JavaScript решение
сопоставлено/оригиналfunction TreeNode(val, left, right) {
this.val = val;
this.left = left;
this.right = right;
}
var rob = function(root) {
var helper = function(node) {
if (!node) {
return [0, 0];
}
let left = helper(node.left);
let right = helper(node.right);
let rob = node.val + left[1] + right[1];
let notRob = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
return [rob, notRob];
};
let answer = helper(root);
return Math.max(answer[0], answer[1]);
};
Python решение
сопоставлено/оригиналclass TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def rob(self, root: TreeNode) -> int:
def helper(node):
if not node:
return (0, 0)
left = helper(node.left)
right = helper(node.right)
rob = node.val + left[1] + right[1]
not_rob = max(left) + max(right)
return (rob, not_rob)
answer = helper(root)
return max(answer)
Go решение
сопоставлено/оригиналtype TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func rob(root *TreeNode) int {
res := helper(root)
return max(res[0], res[1])
}
func helper(node *TreeNode) [2]int {
if node == nil {
return [2]int{0, 0}
}
left := helper(node.Left)
right := helper(node.Right)
rob := node.Val + left[1] + right[1]
notRob := max(left[0], left[1]) + max(right[0], right[1])
return [2]int{rob, notRob}
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
Algorithm
Инициализация и базовый случай:
Создайте вспомогательную функцию helper, которая принимает узел в качестве входных данных и возвращает массив из двух элементов, где первый элемент представляет максимальную сумму денег, которую можно украсть, если не грабить этот узел, а второй элемент - если грабить этот узел.
Базовый случай для вспомогательной функции - узел null, и в этом случае функция возвращает массив из двух нулей [0, 0].
Рекурсивное исследование дерева:
В функции helper вызывайте её рекурсивно для левого и правого поддеревьев текущего узла.
Если грабить текущий узел, то нельзя грабить его потомков, поэтому сумма будет равна значению текущего узла плюс максимальные суммы для случаев, когда потомки не грабятся.
Если не грабить текущий узел, то можно свободно выбирать, грабить потомков или нет, поэтому сумма будет равна максимальной сумме из двух вариантов для каждого потомка.
Возврат результата:
В основной функции rob вызовите helper для корня дерева и верните максимальное значение из двух элементов массива, возвращенного функцией helper.
😎
Вакансии для этой задачи
Показаны активные вакансии с пересечением по тегам задачи.