Java 搜索时间复杂度较低的数组

Java 搜索时间复杂度较低的数组,java,arrays,algorithm,search,time-complexity,Java,Arrays,Algorithm,Search,Time Complexity,向所有程序员致意 我想介绍我的方法来搜索时间复杂度较低的未排序数组(整数/字符串)。线性搜索方法通常用于最坏情况时间复杂度为O(n)的未排序阵列 我修改了线性搜索条件,也检查了数组的最后一个元素,从而减少了迭代次数。请检查此代码并提供宝贵的反馈。这里是在O(n/2)中搜索循环的最坏情况时间复杂度。[编辑-通过回答,知道它仍然是O(n)] for(int i=0,len=arr.length;i在完全未知结构中搜索时,我们不能比线性搜索做得更好。底线是:我们需要查看每个元素以找到特定的元素(产生O

向所有程序员致意

我想介绍我的方法来搜索时间复杂度较低的未排序数组(整数/字符串)。线性搜索方法通常用于最坏情况时间复杂度为O(n)的未排序阵列

我修改了线性搜索条件,也检查了数组的最后一个元素,从而减少了迭代次数。请检查此代码并提供宝贵的反馈。这里是在O(n/2)中搜索循环的最坏情况时间复杂度。[编辑-通过回答,知道它仍然是O(n)]


for(int i=0,len=arr.length;i在完全未知结构中搜索时,我们不能比线性搜索做得更好。底线是:我们需要查看每个元素以找到特定的元素(产生
O(n)

从左到右、从右到左、从两边甚至从任意位置搜索都无关紧要。如果我们对结构没有任何知识,那么它就不重要了


然而,如果我们知道某件事,例如结构被分类或任何其他类型的特殊分布,那么我们可以利用它并利用它

只有在这种情况下,我们才能开发出更为复杂的技术,例如对排序结构进行二元搜索


它认为,只要你不限制输入的结构(因此允许每个任意的输入结构),那么你总是可以找到一种特殊类型的输入,为每个算法生成
n-查找

如果我让你正确,那么你的特殊算法从两边处理列表,所以一个线性搜索从左开始,从右开始,最后在中间相遇。

对于这种特殊算法,您可以在所需元素正好位于中间位置的位置生成输入,然后再次进行
n-lookup


在这一点上,我认为你可能会被这些特征弄糊涂

如果您在一次迭代中进行两次比较,甚至100次比较,则不会降低时间复杂度。虽然您的算法最终只有
n/2次
迭代是正确的(因为它在一次迭代中进行了两次查找),但它将再次生成
n次查找

还要注意的是,即使您的算法真的只需查看
n/2
元素,根据定义,它也将再次位于
O(n)
的集合中(您可以忽略所有常量因子,例如O表示法中的
1/2

就像一个粗略的概述一样:在集合
O(g(x))
中,所有函数
f(x)
都是假设您为其编写的
f(x)函数

if(arr[0].equals(somethingToFind) || arr[1].equals(somethingToFind) || arr[2].equals(somethingToFind) || arr[3].equals(somethingToFind) || arr[4].equals(somethingToFind)){
            System.out.println("Found");
            break;
       }

在最坏的情况下,您的目标位于最后一个索引中。因此它将是O(n)。

正如@Kayaman所评论的,搜索未排序的数组总是O(n)

这个问题的答案有一个证明:


假设你的算法将数组的大小增加了一倍。你的算法需要多少时间?将时间增加一倍。这就是O(n)的意思。

即使你在一个if中放入两个条件,你每次迭代都要访问数组2次。同样,在渐近符号中,O(n/2)仍然等于O(n)。 因此,在未排序的数组中搜索元素时,不可能得到比O(n)更好的结果。

您正在(不知不觉地)执行的操作称为循环展开,即在循环体中复制指令以减少迭代次数和循环开销

在这种情况下,你所做的完全适得其反,原因有二:

  • 您可以用一个循环退出测试来换取一个快捷方式,或者,可能更难预测分支

  • 你在两个地方扫描内存,而不是一个,一个相反。这是不友好的缓存


正如其他人所说,在最坏的情况下,不可能在少于N次的比较中执行此查找。(最坏的情况发生在搜索的元素不在列表中时。)

不,它仍然是O(N)。不能在少于O(N)次的比较中搜索未排序的数组@Kayaman不是真的,用量子计算,你can@DamianLattenero是的,但这在Java 13之前是不可用的。像这样考虑一下——你如何保证元素存在于未排序的数组中,而不查看数组中的每个元素?并且查看数组中的每个元素是O(n),而不管你如何遍历它。@Thuvi,另一种看待它的方式。根据你的解决方案,如果集合的大小增加了10倍,它仍然需要10倍的时间来处理。线性增长。这不是OP写的,也不是OP的代码进行检查的顺序。OP给出了一个arr[i]的示例。等于(somethingToFind)| | arr[--len].equals(somethingToFind),我将其转化为更具体的风格来表明,无论你做什么,在这种搜索中,你最终都会得到O(n)。为清晰起见,所提到的问题声明:数组搜索NP完全。线性复杂度O(n)实际上不是NP完全的。这也在该问题的答案中得到了解释
if(arr[0].equals(somethingToFind) || arr[1].equals(somethingToFind) || arr[2].equals(somethingToFind) || arr[3].equals(somethingToFind) || arr[4].equals(somethingToFind)){
            System.out.println("Found");
            break;
       }