非二叉树高度(优化)

时间:2018-07-04 14:43:41

标签: python python-3.x tree

简介

所以我正在上edX的课程,并且一直在为 3小时的大部分时间,但我仍然找不到实现此方法的方法 无需花费太多时间和自动分级机的时间。

我尝试了3种不同的方法,所有这些方法都做同样的事情。 包括2种递归方法和1种非递归方法(我最新)。

我认为我的代码遇到的问题是查找子代的方法花了很长时间,因为它必须遍历整个节点列表。

输入和输出格式

输入在第一行包含N,这是第2行给出的列表大小。

示例:

5
-1 0 4 0 3

要以此构建一棵树: 数组中的每个值都是指向数组中另一个索引的指针,因此在上面的示例中,0是-1(索引0)的子节点。由于-1指向其他索引,因此它是根节点。

该示例中的树具有根节点-1,该节点具有两个子节点0(索引1)和0(索引3)。索引为1的0没有子级,索引3的0有1个子级:3(索引4),而子级3则只有一个子级4(索引2)。

上述输入的输出为4。这是因为与其他分支的高度相比,包括-1(根节点),0、3和4的分支的最大高度为4。 (-1和0),即高度2。

如果您需要更详尽的解释,那么我可以在评论中再举一个例子!

输出是树的最大高度。输入的大小增加到 100,000 ,这正是我遇到的麻烦,因为它必须在恰好3秒或更短的时间内完成

我的代码

这是我最新的非递归方法,我认为这是我做的最快的方法(仍然不够快)。我使用了网站上的启动器,该启动器还将包含在代码下方。无论如何,谢谢您的帮助!

我的代码:

# python3

import sys, threading
sys.setrecursionlimit(10**7) # max depth of recursion
threading.stack_size(2**27)  # new thread will get stack of such size

def height(node, parent_list):
        h = 0
        while not node == -1:
                h = h + 1
                node = parent_list[node]
        return h + 1

def search_bottom_nodes(parent_list):
        bottom_nodes = []
        for index, value in enumerate(parent_list):
                children = [i for i, x in enumerate(parent_list) if x == index]
                if len(children) == 0:
                        bottom_nodes.append(value)

        return bottom_nodes

class TreeHeight:
        def read(self):
                self.n = int(sys.stdin.readline())
                self.parent = list(map(int, sys.stdin.readline().split()))

        def compute_height(self):
                # Replace this code with a faster implementation
                bottom_nodes = search_bottom_nodes(self.parent)
                h = 0
                for index, value in enumerate(bottom_nodes):
                        h = max(height(value, self.parent), h)
                return h


def main():
  tree = TreeHeight()
  tree.read()
  print(tree.compute_height())

threading.Thread(target=main).start()

edX启动器:

# python3

import sys, threading
sys.setrecursionlimit(10**7) # max depth of recursion
threading.stack_size(2**27)  # new thread will get stack of such size

class TreeHeight:
        def read(self):
                self.n = int(sys.stdin.readline())
                self.parent = list(map(int, sys.stdin.readline().split()))

        def compute_height(self):
                # Replace this code with a faster implementation
                maxHeight = 0
                for vertex in range(self.n):
                        height = 0
                        i = vertex
                        while i != -1:
                                height += 1
                                i = self.parent[i]
                        maxHeight = max(maxHeight, height);
                return maxHeight;

def main():
  tree = TreeHeight()
  tree.read()
  print(tree.compute_height())

threading.Thread(target=main).start()

1 个答案:

答案 0 :(得分:1)

只需在dict中缓存先前遍历的节点的先前计算的高度,并在它们被称为父节点时重新使用它们即可。

import sys, threading
sys.setrecursionlimit(10**7) # max depth of recursion
threading.stack_size(2**27)  # new thread will get stack of such size

class TreeHeight:
    def height(self, node):
        if node == -1:
            return 0
        if self.parent[node] in self.heights:
            self.heights[node] = self.heights[self.parent[node]] + 1
        else:
            self.heights[node] = self.height(self.parent[node]) + 1
        return self.heights[node]

    def read(self):
        self.n = int(sys.stdin.readline())
        self.parent = list(map(int, sys.stdin.readline().split()))
        self.heights = {}

    def compute_height(self):
        maxHeight = 0
        for vertex in range(self.n):
            maxHeight = max(maxHeight, self.height(vertex))
        return maxHeight;

def main():
    tree = TreeHeight()
    tree.read()
    print(tree.compute_height())

threading.Thread(target=main).start()

从您的问题中得到相同的输入,此(和您的原始代码)输出:

4
相关问题