【问题标题】:How to determine if my code is O(n), O(nlogn),O(1),O(n^2)? [duplicate]如何确定我的代码是否为 O(n)、O(nlogn)、O(1)、O(n^2)? [复制]
【发布时间】:2021-02-18 02:51:57
【问题描述】:

我很难理解如何确定我的程序的运行时间,有没有简单的方法可以做到这一点?另外,当我尝试搜索数组中的特定元素时,为什么时间复杂度是 O(1) 而不是 O(n)? (我认为是 O(n),因为在最坏的情况下,您必须遍历整个数组才能确定元素是否存在)

【问题讨论】:

  • 如果说时间复杂度是O(1)那么很可能是一个hashtable
  • 你是对的:搜索数组不能是 O(1) (除非你只搜索第一个元素......)。如果数组未排序,则必须进行线性搜索,即 O(n)。唯一可以接近 O(1) 搜索时间的数据结构是哈希表。

标签: java algorithm computer-science


【解决方案1】:

O(n) 要求您首先定义“n”可能是什么。说,任务是:

给定一个大小为 t 的整数数组 a 和一个特定整数 x,返回xa中出现的第一个索引>;如果 x 不在 a 中,则返回 -1。

然后,我想到了这个算法:

for (int i = 0; i < a.length; i++) if (a[i] == x) return i;
return -1;

这个算法是O(t)

这是什么意思?

好吧,做一个图表。在 x 轴上,放置“所用时间”(或所用内存;您可以根据需要测量空间复杂度或时间复杂度)。在 y 轴上,输入“t”:该数组的大小。

现在,开始运行您的算法。首先是一个 1 大小的数组,然后是一个 2 大小的数组,然后继续。最终是一个百万大小的数组。把它画出来。

在 0 点附近(小阵列)到处都是。 wild 摆动 - 你更多地测量 JVM 启动时间,你的音乐播放器是否正在切换到下一首曲目,你的浏览器是否在做一些工作,谁知道呢。一团糟。但最终这条线会稳定下来。一旦您的输入数组中有几百万个项目,热点启动、VM 预热、音乐播放器 - 这些都不再对测量产生有意义的影响。

一旦线路稳定下来,它会是什么样子?

O(n) 算法说:“它看起来像一条非水平直线”。因为如果你绘制y = C*x,(为C选择任何常数),那看起来就像一条非水平直线。

O(1) 算法看起来像一条水平线(为什么?因为 y = C 看起来像那样)。 O(n^2) 算法看起来就像 y = x^2 所做的那样,如果你绘制它,等等。就像y = 812398x^2 + 234124124x 最终看起来几乎和y = x^2 一样,只要你“向右走得足够远”,在O(x) 表示法中,常数因子和黯然失色的因子(812398 是常数,234124124x部分黯然失色)被忽略。这是关于“图表最终会是什么样子?”,而这些方面根本不会影响这一点。

现在您知道O(n) 的含义了。然后解释为什么这个算法是O(n) 是微不足道的:如果你的数组中有一百万个数字,你必须查看潜在的一百万个条目来找出答案。谁告诉你它是O(1) 是错误的,或者你更有可能听错了。也许他们在谈论:

为这个任务提供一些优化的集合,确定给定整数 x 是否在数据结构 a 中有多难?里面有 t 个元素吗?

对于数组,答案是O(n),但如果aHashSet,答案是O(1)。哈希集不需要检查每个元素。

【讨论】:

    【解决方案2】:

    在数组中搜索是 O(n)。就像这样,如果您的数组中有 n 项,则您要查找的项有可能位于数组的末尾。所以你需要检查每个元素,我们称之为动作。由于有 n 个元素,因此有 n 个动作,因此 O(n)。

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 2012-11-22
      相关资源
      最近更新 更多