Java 二维数组的深度优先搜索

Java 二维数组的深度优先搜索,java,algorithm,search,data-structures,stack,Java,Algorithm,Search,Data Structures,Stack,我有一个这样的数组: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 我想把“1”元素分组 你看,我有一个使用堆栈的经典dfs。问题是,如果我有一个像上面这样的矩阵,这个算法的时间复杂度是多少,其中n是矩阵元素的数目。Row*column。如果由于我必须遍历整个2D数组,所以它比O

我有一个这样的数组:

0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0 0 0 0
0 1 1 1 1 0 0 1 0 1 0
0 1 1 0 1 0 0 0 0 1 1
0 0 0 1 1 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0
我想把“1”元素分组

你看,我有一个使用堆栈的经典dfs。问题是,如果我有一个像上面这样的矩阵,这个算法的时间复杂度是多少,其中n是矩阵元素的数目。Row*column。如果由于我必须遍历整个2D数组,所以它比ON更糟糕,那么哪种方法可以帮助我改进此算法

On*logn算法示例 其中n是矩阵元素的数量

该算法的思想如下

通过将所有矩阵元素添加到树集中,初始化未处理元素U的树集 当U还不是空的时候,从U中取出任何U并检查它的值 如果u='0',则只需删除它,即u:=u\{u} 如果u='1',则开始探索DFSu,u 其中程序DFSu,U使用矩阵探索U的“1”邻居

然而,这里来了kicker,DFSu,U也从U中删除了所有发现的元素

很容易理解并证明该算法确实总是在*log n中完成。从树集中删除元素的最坏情况复杂度为Olog n。每个DFSu,U运行最多可以访问| U |个元素,并且随着执行的进行,通过任何方式访问的每个元素都会从U中删除。当U变为空时,算法终止

小结 可以生成一个On^2算法,例如在每个元素上运行DFS,而不考虑您以前获得的知识。 使用任何确保不在已发现的组/岛上运行DFS的机制,都可能产生一种更优的算法


很抱歉,我无法直接分析您自己的算法,但这可能有助于您自己进行分析。

您需要设计的算法的下限应为Om+n-我认为行数和列数分别为m和n。这是因为您无论如何都需要遍历整个二维阵列。如果您使用两个for循环来解决这个问题,那么这也需要Om+n。对于矩阵中的每个元素,您将与其他4个相邻元素进行比较,因此,总体检查大小是您忘记告诉我们N是什么。答案可能是O…你可以通过计算每个像素的访问次数来找到答案。好的,另一种方法。我只会将“1”推到列表中。然后通过单个循环遍历列表,对于每个项目,使用堆栈检查DFS。在删除之前没有问题。DFS删除所有邻居,只保留第一次出现,对吗?这样我就可以在从列表中删除您描述的元素时计算不同孤岛的数量U删除的复杂性在哪里?还是不?。所以它又出现了。我错了吗?只添加'1'听起来像是一个合适的升级,是的。但是,DFS应该删除发现的每个“1”,包括它开始的位置。清空列表U,以便知道何时终止,这一点非常重要。为了记住发现的孤岛,每次运行DFS都可以将此信息存储在其他变量中,但可能不存储在列表U中。从列表中删除特定元素可能会增加复杂性,这一点非常重要。然而,您可以使用一些基于搜索树或哈希表Java集合或映射的更合适的数据结构,它们可以在Olog n甚至O1中实现。对于HashMap,O1并不是最糟糕的情况复杂性。我想,在一个纯粹的世界末日式的最坏情况下,这将使复杂性实际上出现在*logn上。很好。我会修正我的答案。是的,我的意思是r*c=n,它是元素的数量。使用堆栈计算岛屿数量的正确方法是什么。哦。。。我懂了。您确实需要使用堆栈来解决它。现在我明白了。我只是概括问题和解决办法。让我想一想,如果我发现有什么有趣的事情,我会给你回复的。谢谢是的,我试过的所有东西都在^2上卡住了。谢谢。我想,有2个嵌套的for循环,就有r*c,也就是n。然后在这个嵌套循环中,用堆栈搜索得到n。所以总数是n^2。我说得对吗?