Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 分析算法的时间复杂度_Python_Algorithm_Tree_Time Complexity_Big O - Fatal编程技术网

Python 分析算法的时间复杂度

Python 分析算法的时间复杂度,python,algorithm,tree,time-complexity,big-o,Python,Algorithm,Tree,Time Complexity,Big O,在一次采访中,我被要求编写一个函数,给定一棵树和树中的两个节点,将最接近的祖先返回给这两个孩子 这是我的密码: two_paths = [] def get_closest_ancestor(path1, path2): for i in xrange(min(len(path1), len(path2))): if path1[i] != path2[i]: return path1[i-1] def find_two_paths(root

在一次采访中,我被要求编写一个函数,给定一棵树和树中的两个节点,将最接近的祖先返回给这两个孩子

这是我的密码:

two_paths = []

def get_closest_ancestor(path1, path2):

    for i in xrange(min(len(path1), len(path2))):
        if path1[i] != path2[i]:
            return path1[i-1]

def find_two_paths(root, a, b, path = []):
    global two_paths

    newpath = path[:]

    newpath.append(root)

    if len(two_nodes) == 2:
        return

    if root == a:
        two_paths.append(newpath)
    if root == b:
        two_paths.append(newpath)

    for child in root.children:
        find_two_paths(child, a, b, newpath)


if __name__ == "__main__":

    find_two_paths(root, a, b)
    print get_closest_ancestor(two_paths)
然后我被要求给出我刚写的算法的大O复杂度

所以我们有两个函数,
查找两条路径
,和
获取最近的祖先

我的第一个问题是,我们在这里接受什么作为输入。在我们的大O符号中,
n
是什么

我想我们看到的是树的深度是
n

find_two_path
显然执行DFS搜索,因此我认为我们已经具有指数级的时间复杂性

我们能不能利用它是一棵树的事实,说复杂性是
O(b^n)
其中
b
是树的分支因子,而
n
是深度

我们能不能说它是
O(2^n)


我们是否可以忽略
获取最近的祖先
函数,因为它是
O(n)
,并且被
查找两条路径
所压倒?

这绝对不是
O(2^n)
。速度快得多。对于图问题,通常将
n
定义为树中的节点数。让我们总结一下您的算法的作用:

  • 从根目录中查找a然后查找b的DFS(记住指向它们的路径)
  • 逐项比较这些路径,直到发现差异(并返回最后一个公共节点)
  • 对于步骤1。每个节点访问一次,因此性能与节点数成比例。这里有一点值得注意的是,你实际上是短路的(尽管是使用全局的),所以你不考虑所有节点。当然,最坏的情况是
    a
    b
    是我们访问的最后两个节点,因此DFS将是
    O(n)

    对于步骤2,最坏的情况是路径在最后一个节点之前是相同的(
    a
    b
    是兄弟节点)。因此,最差的性能将与最长列表的长度成正比。现在,我们可以对步骤1进行批判性思考,并推断出访问每个节点的O(n)将始终大于或等于步骤2中的最长路径(因此总体而言,
    O(n)
    将占主导地位,并且将是
    O(n)
    时间),但让我们彻底了解一下。如果我们对这棵树有一些保证(比如它是一棵平衡的二叉树),我们可以说最长的路径是
    O(logn)
    ,因此比较这两条路径最坏的情况是
    O(logn)
    。但是我们没有这样的保证。我们可以更一般地说,如果我们可以将图的分支因子(每个节点的子节点的平均数量)近似为
    b
    ,那么我们可以近似地说最长路径是
    O(log_b n)
    。但是对于一般树(最坏的情况是链表),路径是O(n)长度。因此,步骤2也是最坏情况O(n)


    因此,此
    O(n)

    树度量复杂性的总体运行时通常是节点数。缺乏精确回答的假设,特别是关于树中节点的顺序。一个简单的通用解决方案是构造从节点1到根的路径1,然后构造从节点2到根的路径2,同时在每个步骤中验证当前节点是否在路径1中。当然,如果你的树是有序的,一些优化显然是可能的


    假设由n个节点组成的树具有精确的度数d,那么构造path1最差需要log_d(n)个步骤,构造path2最差也需要log_d(n)个步骤,但是对于它的每个步骤,您需要搜索采用log_d(n)的path1。最后需要log_d(n)^2。

    我想说树的大小(节点数)是
    n
    的一个合适指标。您只需在两个根路径中搜索公共条目。所以它应该是O(logn)我们只得到树的根作为输入,不能访问节点
    a
    b
    的父节点,你可能知道这一点,但是编写的代码不起作用(
    two_path
    永远不会写入,使用可变的默认参数--ew-,你应该用
    *two_path
    调用)@BaileyParker为什么不回答这个问题呢?“通常将n定义为访问的节点数”:有了这样的定义,搜索二叉搜索树将是O(n)!你可能是指树中的节点总数?@YvesDaoust确实如此。固定的!