使二叉树的每个节点具有相等的 cookie 所需的最小传输成本
Minimum transfer cost required to make every node of binary tree have equal cookies
给定一棵 二叉树,总共有 n 个节点,每个节点都有一定数量的 cookie,总和为 n 总共 个 cookie.
任务是将其转换为具有相同 cookie 的节点(每个节点 1 个 cookie),并且 最小总传输成本 ,前提是传输成本等于 cookie 的数量在节点之间传输。
Cookie 只能在
a)Parent 至 child
b)Child到parent
例子,
在下面的示例中,第一个 cookie 可以从左侧 child 转移到 parent,成本 = 1,然后转移到右侧 child 以使其在所有节点上均等额外成本为 1。因此最低总成本为 2。
1 2 1
2 0 =====> 1 0 =====> 1 1
(given tree) (transformed tree)
Minimum cost of transfer = 2
我们能有一个最优(时间)算法来解决这个问题吗?
您可以使用post阶(深度优先)遍历从每个子树中收集两个信息。定义:
偏差:它是 预期 cookie 数量(即节点数该子树),以及该子树中 cookie 的实际数量。如果为负,则表示 cookie 不足,并且可以肯定的是,这个数量的 cookie 必须通过该子树的父节点来自其他地方。如果 postive,这表示 cookie 盈余,并且该盈余将需要从该子树移出到父节点。所以不管是负的还是正的,它的绝对值代表了这个子树的根和它的父节点之间的cookie流。
该子树中的传输 成本。这表示沿子树 内 边缘移动 cookie 的成本,既可以填充丢失的 cookie,也可以将 cookie 移离具有多个节点的节点。它还包括将所有多余的 cookie 冒泡到子树的根节点的成本,不包括将它们从那里移到父节点的成本。它还包括将来自父节点的 cookie 分发到子树下方的成本,但不包括将这些 cookie 从父节点获取到根节点的成本。
这里有递推关系。当你有给定节点的左右子树的这对信息时,你可以推导出组合树的那对信息(给定节点是根):
当前树(以给定节点为根)的偏差是它的两个子树的偏差和其中的cookie数量之和当前节点减1。“减1”反映了在当前节点中有1个cookie的目标。
当前树(以给定节点为根)的成本是为其两个子树找到的成本与为该节点找到偏差(参见上一点)。
这是 运行nable JavaScript 片段中的一个实现。以下树是 运行:
2
/ \
0 1
/ \
0 2
答案是 3。
class Node {
constructor(value, left=null, right=null) {
this.value = value;
this.left = left;
this.right = right;
}
transferDiffAndCost() {
let diffLeft = 0, diffRight = 0, costLeft = 0, costRight = 0;
if (this.left) {
[diffLeft, costLeft] = this.left.transferDiffAndCost();
}
if (this.right) {
[diffRight, costRight] = this.right.transferDiffAndCost();
}
let diff = diffLeft + diffRight + this.value - 1;
let cost = costLeft + costRight + Math.abs(diff);
return [diff, cost];
}
transferCost() {
let [diff, cost] = this.transferDiffAndCost();
if (diff != 0) throw "Number of cookies not the same as number of nodes";
return cost;
}
}
// Create tree
let root = new Node(2,
new Node(0,
new Node(0),
new Node(2)
),
new Node(1)
);
console.log(root.transferCost()); // 3
给定一棵 二叉树,总共有 n 个节点,每个节点都有一定数量的 cookie,总和为 n 总共 个 cookie.
任务是将其转换为具有相同 cookie 的节点(每个节点 1 个 cookie),并且 最小总传输成本 ,前提是传输成本等于 cookie 的数量在节点之间传输。
Cookie 只能在 a)Parent 至 child b)Child到parent
例子,
在下面的示例中,第一个 cookie 可以从左侧 child 转移到 parent,成本 = 1,然后转移到右侧 child 以使其在所有节点上均等额外成本为 1。因此最低总成本为 2。
1 2 1
2 0 =====> 1 0 =====> 1 1
(given tree) (transformed tree)
Minimum cost of transfer = 2
我们能有一个最优(时间)算法来解决这个问题吗?
您可以使用post阶(深度优先)遍历从每个子树中收集两个信息。定义:
偏差:它是 预期 cookie 数量(即节点数该子树),以及该子树中 cookie 的实际数量。如果为负,则表示 cookie 不足,并且可以肯定的是,这个数量的 cookie 必须通过该子树的父节点来自其他地方。如果 postive,这表示 cookie 盈余,并且该盈余将需要从该子树移出到父节点。所以不管是负的还是正的,它的绝对值代表了这个子树的根和它的父节点之间的cookie流。
该子树中的传输 成本。这表示沿子树 内 边缘移动 cookie 的成本,既可以填充丢失的 cookie,也可以将 cookie 移离具有多个节点的节点。它还包括将所有多余的 cookie 冒泡到子树的根节点的成本,不包括将它们从那里移到父节点的成本。它还包括将来自父节点的 cookie 分发到子树下方的成本,但不包括将这些 cookie 从父节点获取到根节点的成本。
这里有递推关系。当你有给定节点的左右子树的这对信息时,你可以推导出组合树的那对信息(给定节点是根):
当前树(以给定节点为根)的偏差是它的两个子树的偏差和其中的cookie数量之和当前节点减1。“减1”反映了在当前节点中有1个cookie的目标。
当前树(以给定节点为根)的成本是为其两个子树找到的成本与为该节点找到偏差(参见上一点)。
这是 运行nable JavaScript 片段中的一个实现。以下树是 运行:
2
/ \
0 1
/ \
0 2
答案是 3。
class Node {
constructor(value, left=null, right=null) {
this.value = value;
this.left = left;
this.right = right;
}
transferDiffAndCost() {
let diffLeft = 0, diffRight = 0, costLeft = 0, costRight = 0;
if (this.left) {
[diffLeft, costLeft] = this.left.transferDiffAndCost();
}
if (this.right) {
[diffRight, costRight] = this.right.transferDiffAndCost();
}
let diff = diffLeft + diffRight + this.value - 1;
let cost = costLeft + costRight + Math.abs(diff);
return [diff, cost];
}
transferCost() {
let [diff, cost] = this.transferDiffAndCost();
if (diff != 0) throw "Number of cookies not the same as number of nodes";
return cost;
}
}
// Create tree
let root = new Node(2,
new Node(0,
new Node(0),
new Node(2)
),
new Node(1)
);
console.log(root.transferCost()); // 3