如何解决平衡的系统文件分区编码挑战
在给定父数组的情况下,如何确定树的结构?
您好,我正在为HackerRank进行编码面试。我在网上找不到解决方案,我什至不明白这个问题。我不明白的是,基于给定的父数组的树形结构应该是什么样子。解决该问题的方法很好,但是我更想了解如何根据给定的父数组了解树形结构。
问题:
系统磁盘分区的目录结构表示为树。它的n个目录的编号从 0 到 n-1 ,其中根目录的编号为 0 。树的结构由 parent 数组定义,其中 parent [i] = j 表示目录 i 是以下目录的直接子目录 j 。由于根目录没有父目录,因此它将表示为 parent [0] = -1 。 files_size [i] 中的值表示位于目录 i 中的文件大小(以千字节为单位)的总和,但不包括其子目录。目录内容的大小定义为其所有子目录的大小。通过剪切一个分支将树分成两个较小的树,以使所得子树的大小尽可能接近。
示例
parent = [-1,1,2]
files_size = [1,2,1]
系统结构如下图所示。节点标记为 /
剪切目录1和0之间的分支。
分区{0,5}的大小为 files_size [0] + files_size [2] + files_size [5] = 1 + 2 +1 = 4。
分区{1,3,4}的大小为 files_size [1] + files_size [3] + files_size [4] = 2 +1 + 1 = 4。
两棵新树的大小之间的绝对差为 4-4 = 0。
由于没有其他分区可以具有较小的绝对差,因此最终答案为 0 。
功能描述
在下面的编辑器中完成功能 mostBalancedPartition 。
该函数具有以下参数:
int parent [n] :每个 parent [i] 是目录 i
的父目录
int files_size [n] :每个 file_sizes [i] 是目录 i
返回
int:两个子树之间内容大小的最小绝对差值
约束
2
1
parent [0] = -1
1
的 parent [i]
每个目录树的深度最多为500。
样本输入
父级= [-1,4,4]
示例输出
2
说明
系统结构如下图所示。
剪切目录 1 和 2 之间的分支。这将导致分区 {0,1} 的大小为 1 + 4 = 5 和 {2,3} 的大小为 3 + 4 = 7 。它们的大小之间的绝对差为 | 5-7 | = 2
样本输入
父级= [-1,0]
files_size = [10,11,10,10]
示例输出
19
说明
系统结构如下图所示。
剪切目录 0 和 1 之间的分支。这将导致分区 {0,3} 的大小为 10 + 10 + 10 = 30 ,而分区 {1} 的大小为 11 。它们的大小之间的绝对差为 | 30-11 | = 19
样本输入
父= [-1,0,1,2,1,0,5,2,0,0]
files_size = [8475,6038,8072,7298,5363,9732,3786,5521,8295,6186]
示例输出
4182
样本输入
父= [-1,0,0,0,0,3,4,6,6,0,3]
files_size = [298,2187,5054,266,1989,6499,5450,2205,5893,8095]
示例输出
8216
解决方法
def mostBalancedPartition(parent,files_size):
# Write your code here
def helper(node,adj,files_size):
queue = [node]
weight = 0
while queue:
index = queue.pop()
weight += files_size[index]
if index in adj:
queue.extend(adj[index])
return weight
adj = {}
edges = []
for index,p in enumerate(parent):
edges.append((p,index))
if p in adj:
adj[p].append(index)
else:
adj[p] = [index]
print(adj,edges)
total_weight = sum(files_size);
min_diff = sum(files_size);
for e in edges:
p,c = e
adj[p].remove(c)
w1 = helper(c,files_size)
min_diff = min(min_diff,abs(total_weight - 2*w1))
adj[p].append(c)
return min_diff
,
def json
def Balance(parent,files_size):
diff=[]
count=1
for _ in range(1,len(parent)):
index=range(len(parent))
ind=list(index)
ind.remove(count)
edge1 = [i for i in ind if parent[i]!=count]
edge2 = [i for i in index if i not in edge1]
filtered_list = list(filter(lambda i: parent[i] not in edge2,edge1))
for i in edge1:
if i not in filtered_list:
edge2.append(i)
count+=1
partiton1=[]
for i in filtered_list:
partiton1.append(files_size[i])
partition2 =[]
for j in edge2:
partition2.append(files_size[j])<br/>
diff.append(abs(sum(partiton1)-sum(partition2)))
print(min(diff))
,
package main
import (
"fmt"
"math"
)
func main() {
parent := []int32{-1,1,2}
fileSize := []int32{1,2,1}
//find all edges
edges := make([][2]int,0)
length := len(parent)
for k,_ := range parent {
for i := k + 1; i < length; i++ {
if parent[i] == int32(k) {
edges = append(edges,[...]int{k,i})
}
}
}
//get sons
var getSons func(node int) (nodeList []int)
getSons = func(node int) (nodeList []int) {
for k,v := range parent {
if v == int32(node) {
nodeList = append(nodeList,k)
nodeList = append(nodeList,getSons(k)...)
}
}
return
}
totalFileSize := 0
for _,v := range fileSize {
totalFileSize += int(v)
}
diffList := make([]int,0)
for _,v := range edges {
var nodeList = []int{v[1]}
var sons = getSons(v[1])
nodeList = append(nodeList,sons...)
fileSize1 := 0
for _,v := range nodeList {
fileSize1 += int(fileSize[v])
}
diff := 2 * fileSize1 - totalFileSize
diffList = append(diffList,int(math.Abs(float64(diff))))
}
min := diffList[0]
for _,v := range diffList {
if v < min {
min = v
}
}
fmt.Println(min)
}
,
计算整个树的大小,然后计算所有可能的子树的大小就足够了。通过最小化 abs(total_size - (2 * sub_size)) 我们找到最平衡的分区。
import sys
class Tree:
def __init__(self,root,nodes):
self.root = root
self.children = []
for node in nodes:
if node[1] == self.root[0]:
# recursively construct tree
t = Tree(node,nodes)
self.children.append(t)
def size(self):
return self.root[2] + sum([x.size() for x in self.children])
def subtree_sizes(self,result=[]):
for x in self.children:
result.append(x.size())
x.subtree_sizes(result)
return result
def build_tree(parent,files_size):
result = list()
for i in range(len(parent)):
node = i,parent[i],files_size[i]
if parent[i] == -1:
root = node
else:
result.append(node)
t = Tree(root,result)
return t
def mostBalancedPartition(parent,files_size):
tt = build_tree(parents,file_sizes)
total_size = tt.size()
return min([abs(total_size - 2*x) for x in tt.subtree_sizes()])
,
def mostBalancedPartition(parent,files_size):
queue = [node]
weight = 0
while queue:
index = queue.pop()
weight += files_size[index]
if index in adj:
queue.extend(adj[index])
return weight
adj = {}
edges = []
for index,edges)
total_weight = sum(files_size)
min_diff = sum(files_size)
for e in edges:
p,abs(total_weight - 2*w1))
adj[p].append(c)
return min_diff
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。