Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.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 说这个算法是O(n+m)正确吗?_Python_Algorithm_Graph_Time Complexity_Big O - Fatal编程技术网

Python 说这个算法是O(n+m)正确吗?

Python 说这个算法是O(n+m)正确吗?,python,algorithm,graph,time-complexity,big-o,Python,Algorithm,Graph,Time Complexity,Big O,首先,我研究了以下问题: 然而,我仍然没有100%的信心。也就是说,我有以下python示例代码: 我开始认为这是一个On+m算法,以下是我的推理: 我有一个adjList,它是一个列表列表。为了举例说明,这里的整数是随机选取的。这实际上是一个邻接列表,其中顶点1链接到顶点4、7、8和9,依此类推 我知道adjList[I][j]将返回第I个列表中的第j个项目。所以adjList[0][2]是8 第一个for将在每个i列表中循环。如果我们有N个列表,这是一个ON 第二个for将遍历列表中的每

首先,我研究了以下问题:

然而,我仍然没有100%的信心。也就是说,我有以下python示例代码:

我开始认为这是一个On+m算法,以下是我的推理:

我有一个adjList,它是一个列表列表。为了举例说明,这里的整数是随机选取的。这实际上是一个邻接列表,其中顶点1链接到顶点4、7、8和9,依此类推

我知道adjList[I][j]将返回第I个列表中的第j个项目。所以adjList[0][2]是8

第一个for将在每个i列表中循环。如果我们有N个列表,这是一个ON

第二个for将遍历列表中的每个j元素。但在这种情况下,j不是固定值,例如,第一个列表有4个元素4,7,8,9,第三个列表有3个元素1,4,3。因此在最后,第二个for将循环M次,M是每个不同j值的总和。所以,M是每个列表的元素之和。因此,OM

在本例中,第一个for应循环5次,第二个for应循环16次。总共有21个循环。如果我将adjList更改为如下列表中的单个大列表:

adjList = [[4,7,8,9,7,7,5,6,1,4,3,2,9,2,1,7]]
for i in adjList:
    <something significant 1>   
    for j in i:
        <something significant 2>
它仍然会在第二个元素中循环16个元素,在第一个元素中循环1次

因此,我可以说该算法将循环N次加上M次。其中N是adjList中列表的数量,M是adjList中每个列表中元素的总和。依此类推+M

那么,我的怀疑在哪里? 我在任何地方都能找到嵌套循环在^2或*M上的例子。即使人们提到它们可能是其他的东西,但我没有发现任何例子。我还没有找到ON+m嵌套循环的示例。所以我仍然怀疑我的推理是否正确

我怀疑这是否不是一个ON*M算法。但我不会详细说明这一点。
因此,我的最后一个问题仍然是:这个推理是否正确,所说的算法是否确实在+M上?如果没有,请告诉我我的错误在哪里好吗

你最大的错误是你没有清楚地识别M和N的含义

例如:

访问nxm矩阵中的所有单元是在*M上。 如果你把这个矩阵展平成一个有P个单元格的列表,访问就是OP。 然而,在这个上下文中,P==N*M。。。所以OM*N和OP的意思是一样的。。。在这方面。 看看你的推理,你似乎把你的M和我的p的模拟混为一谈了。我说模拟是因为矩形阵列和参差不齐的阵列是不一样的

所以,M是每个列表的元素之和

这不是我使用M的方式。更重要的是,这不是你所看到的其他各种参考文献使用M的方式。特别是那些讨论nxm矩阵或nxmavgem不规则数组的参考文献。因此你感到困惑

请注意,M和N不是独立变量/参数。如果以N来缩放问题,则会隐式更改M的值


提示:在对复杂性进行推理时,确保得到正确答案的一种方法是回到基础。计算出计算所执行操作的公式,并说明原因,而不是试图说明大O符号的组成方式。

如果您的代码如下所示:

adjList = [[4,7,8,9,7,7,5,6,1,4,3,2,9,2,1,7]]
for i in adjList:
    <something significant 1>   
    for j in i:
        <something significant 2>

您将N和M定义如下:

因此,我可以说该算法将循环N次加上M次。其中N是adjList中列表的数量,M是adjList中每个列表中元素的总和。依此类推+M

根据这个定义,算法是OM1。要理解为什么N消失,你需要考虑N和M之间的关系。假设你有两个列表,并且你想从两个列表中查看每一个可能的项目对。我们将保持简单:

list1 = [1, 2, 3]
list2 = [4, 5]
所以你想看看这六对:

pairs = [(1, 4), (2, 4), (3, 4), (1, 5), (2, 5), (3, 5)]
总共是3*2=6。现在概括一下;假设列表1有N个项目,列表2有M个项目。对的总数是N*M,因此这将是一个ON*M算法

现在假设您不需要查看每一对,而只需要查看一个或另一个列表中的每一项。现在,您只需查看两个列表串联中出现的所有值:

items = [1, 2, 3, 4, 5]
总共是3+2=5项。现在概括;你将得到N+M,这将是一个ON+M算法

鉴于此,如果您的案例确实在+M上,我们应该期望您的案例与上述案例相同。换句话说,我们应该期望您的案例涉及查看两个不同列表中的所有项目。但是你看:

all_lists = [[4,7,8,9],[7,7,5,6],[1,4,3],[2,9],[2,1,7]]
这与:

list1 = [4,7,8,9]
list2 = [7,7,5,6]
list3 = [1,4,3]
list4 = [2,9]
list5 = [2,1,7]
而在ON+M的情况下,只有两个列表,这里有五个列表!所以这个不能在+M上

然而,这应该给你一个如何做出更好的描述的想法。提示:除了M和N之外,它还可以包括J、K和L

错误的根源在于,在前两个例子中,M和N被定义为彼此独立 呃,但是你对M和N的定义是重叠的。为了使M和N有意义地相加或相乘,它们需要彼此无关。但在你的定义中,M和N的值是相互关联的,所以在某种意义上,它们重复了不应该重复的值

或者,用另一种方式说,假设所有内部列表的长度之和加起来是M。如果你必须采取两个步骤,而不是每个值只采取一个步骤,那么结果仍然只是一个常量值C乘以M。对于任何常量值C,C*OM仍然是OM。因此,在外循环中所做的功已经被OM项计算为一个常数乘数

注:

一,。嗯,好吧,不完全是,正如所指出的。由于技术上的原因,说OmaxN可能更合适,
因为如果任何内部列表都是空的,您仍然需要访问它们。

n和M是什么?喂?你已经对这个不感兴趣了吗?OP已经定义N为子列表的数量,M为整个嵌套列表中的整数总数。是的。。。但这与他所研究的其他来源对M和N的定义不同,OP的定义意味着M和N不是自变量,不是OM。假设M为0,即所有子列表都为空。@StefanPochmann我不包括仅仅执行循环的工作。“听起来你是,”斯蒂芬波希曼我想在某些计算模型下,你可以。但我认为你的观点是正确的,并且可能部分解释了为什么这是一个令人困惑的问题。@StefanPochmann one通常不会将每个语句和表达式都考虑到运行时的计算中。你看最贵的零件。在这种情况下,这是打印。这是一个近似值,是实用性所必需的。否则,您将用尽字母表中的所有字母来查找任何合理复杂算法的运行时间。@如果M是0,N是万亿,那么打印不是最昂贵的部分。一次也不跑。它花费零时间。但代码确实要经过一万亿个列表,这确实需要花费时间。很多你不能忽视这一点。