微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

平衡的系统文件分区编码挑战

如何解决平衡的系统文件分区编码挑战

在给定父数组的情况下,如何确定树的结构?

您好,我正在为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]

系统结构如下图所示。节点标记 /

example one tree structure


剪切目录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
说明
系统结构如下图所示。

enter image description here


剪切目录 1 2 间的分支。这将导致分区 {0,1} 的大小为 1 + 4 = 5 {2,3} 的大小为 3 + 4 = 7 。它们的大小之间的绝对差为 | 5-7 | = 2

样本输入
父级= [-1,0]
files_size = [10,11,10,10]
示例输出
19
说明
系统结构如下图所示。

enter image description here


剪切目录 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 举报,一经查实,本站将立刻删除。