【问题标题】:Is the Time Complexity of assigning n values to an array of size n O(n)?将 n 值分配给大小为 n 的数组的时间复杂度是 O(n) 吗?
【发布时间】:2019-10-14 21:03:56
【问题描述】:

我正在尝试在哈希中使用索引映射来搜索数组中的元素。线性搜索将花费 O(n) 来搜索大小为 n 的数组中的元素。在散列中,我们所做的基本上是通过创建一个 2d 零矩阵(例如 hash[1000][2])并将 hash[a[i]][0] 重新分配为 1,从而将时间复杂度降低到 O(1) a[i] 为正数,如果 a[i] 为负数,则为 hash[-a[i]][1]。这里 a[i] 是我们应该从中搜索元素的数组。

    for(i=0 ;i<n    ;i++)
    {
        if(a[i]>=0)
            has[a[i]][0]=1;
        else
            has[-a[i]][1]=1;
    }

上面的代码执行需要多少时间? 即使通过散列,我们不是像线性搜索一样具有 O(n) 的时间复杂度吗?在二维零数组中分配 n 个 1 所消耗的时间不等于以线性方式搜索元素所花费的时间吗?

【问题讨论】:

  • 是的。但该时间只使用一次,而不是每次搜索时。
  • 是的,创建哈希数组需要 O(n),但是每个查询需要 O(1) 时间。所以如果有O(n)个查询,使用哈希数组的时间复杂度是O(n)。但是对 O(n) 查询执行线性搜索需要 O(n^2) 时间。换句话说,构建散列数组来满足一个查询是没有意义的。但是,如果查询节省的时间可以弥补构建表所用的时间,那么它确实有意义。
  • 理论上是的,您的复杂性将是 O(n) + O(1),即 O(n),但实际上它会优于您的线性搜索(假设您的散列方式不不会导致太多的碰撞)。
  • 是的!现在完全有道理。谢谢!
  • 创建哈希数组需要 O(n),但创建线性搜索数组也需要 O(n)。

标签: c indexing hash time-complexity


【解决方案1】:

这里的典型做法是维护一个按哈希键排序的数组,然后使用二进制搜索来定位元素,最坏情况下的时间复杂度为 O(log n)。

您可以使用与查找现有元素相同的二进制搜索插入新元素来维护排序顺序。

最后一点很重要:如 cmets 中所述,在每次搜索之前进行排序会降低搜索时间,从而使暴力线性搜索对于小型数据集更快。但是可以消除这种开销;如果在插入新元素时保持排序顺序,则数组永远不需要排序

【讨论】:

  • "维护一个按哈希键排序的数组,然后使用二进制搜索" - 哈希的点通常是为了启用哈希表,当你'重新使用您可以直接索引而无需二进制搜索。而且您在插入期间维护排序顺序的说法具有误导性:如果您有一个排序数组,您可以通过二进制搜索来确定在哪里插入新元素,但是必须在之后对所有现有元素执行 O(n) 移动操作插入点为新元素腾出空间。二叉搜索树和哈希表允许相对高效的插入和擦除;不是这样的数组。
  • 当然,这并不是要误导,而是像其他任何事情一样进行权衡。优点是 1)你不会从一堆空无一物的空间开始;一切都是浓缩的,随着它的增长,你 2)不要在桶里有一堆东西,一旦你找到它就需要 O(n) 时间,或者 3)需要调整整个哈希表的大小以允许更多的桶,每个桶里的东西更少。我发现它适用于存储值经常更改但不经常创建/删除键的情况,尤其是。当您偶尔需要遍历所有存储的值时。
猜你喜欢
  • 1970-01-01
  • 2013-10-20
  • 2021-08-30
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
相关资源
最近更新 更多