Algorithm 非常困难的排序算法问题-O(n)时间-时间复杂

Algorithm 非常困难的排序算法问题-O(n)时间-时间复杂,algorithm,sorting,time-complexity,Algorithm,Sorting,Time Complexity,由于这个问题很长,我无法在标题中描述它 假设我们有两个未排序的整数数组。两个数组长度均为n,并且它们包含介于0-n^765(最大n次方765)之间的intereger 我想比较两个数组,看看它们是否包含相同的整数值,时间复杂度为O(n) 同一阵列中不可能存在重复项 非常感谢您的帮助和建议。我认为您做不到。 您应该检查n个值是否在另一个数组中。这意味着,如果另一个数组只有1个元素,则至少有n个比较操作。但是,由于有n个元素,它也可以是另一个数组,所以只需要O(n*n)就可以了。每个元素将存储在最多

由于这个问题很长,我无法在标题中描述它

假设我们有两个未排序的整数数组。两个数组长度均为n,并且它们包含介于0-n^765(最大n次方765)之间的intereger

我想比较两个数组,看看它们是否包含相同的整数值,时间复杂度为O(n)

同一阵列中不可能存在重复项


非常感谢您的帮助和建议。

我认为您做不到。
您应该检查n个值是否在另一个数组中。这意味着,如果另一个数组只有1个元素,则至少有n个比较操作。但是,由于有n个元素,它也可以是另一个数组,所以只需要O(n*n)

就可以了。每个元素将存储在最多为log(n^765)位的数据中,即O(logn)。因此,简单地读取两个数组的内容需要O(n*logn)

如果每个元素的值都有一个常量上限,则可以通过将一个数组的元素存储在哈希表中,然后检查另一个数组的元素是否包含在哈希表中,在O(n)个平均时间内解决此问题

编辑


您可能正在寻找的解决方案是对数据进行排序,然后可以轻松地检查重复的元素。您可以查看以n为基数的数字,并对数据进行765次传递。每次传递都将使用桶排序或计数排序按单个数字(以n为基数)进行排序。在最坏的情况下(假设元素大小的上限不变),此过程将花费O(n)时间。请注意,我怀疑在实践中是否有人会选择这个而不是哈希表。

如果内存是无限的,您可以简单地创建一个哈希表,其中整数作为键,值是找到它们的次数。然后,要进行“快速”查找,只需查询一个整数,发现它是否包含在哈希表中,如果找到,则检查值是否为1或2。这需要O(n)来加载,O(1)来查询。

假设乘法和除法是O(1):

想想数字,你可以把它们写成:

数字(i)=A0*n^765+A1*n^764+..+A764*n+A765.

要将数字编码为这种格式,您只需执行数字/n^i,数字%n^i,若您预先计算,则n^1,n^2,n^3。。。对于所有数字,都可以用O(n*765)=>O(n)来完成。n^i的预计算可以在O(i)中完成,因为
i
最多是765,所有项目都是O(1)

现在,您可以将数字(i)写为数组:Nembers(i)=(A0,A1,…,A765),并且知道您可以对项目进行基数排序:

首先比较所有A765,然后….,所有Ai都在0..n范围内,因此对于比较Ai,可以使用(计数排序为O(n)),因此基数排序为O(n*765),即O(n)

在基数排序之后,您有两个排序数组,您可以简单地在O(n)中查找一个相似项,或者使用(如合并排序)查找最可能的相似项(而不仅仅是一个)

对于一般化,如果输入项的大小为O(n^C),则可以按O(n)(C是固定数字)排序。但是,由于这种排序方式的开销很大,我们更愿意使用快速排序和类似的算法。这个问题的简单示例可以在书中找到,它询问数字是否在(0..n^2)范围内,如何按O(n)排序

编辑:用于说明如何在2排序列表中找到类似项:

您有两个排序列表,例如在“合并排序”中,如何将两个排序列表合并到一个列表?您将从列表1和列表2的开头移动,并在head(列表(1))>head(列表(2))的同时移动列表1的head指针,然后对列表2和…执行此操作,因此如果存在类似的项,您的算法将停止(在到达列表末尾之前),或者在两个列表的末尾,您的算法将停止

这很容易做到:

public int FindSimilarityInSortedLists(List<int> list1, List<int> list2)
{
   int i = 0;
   int j = 0;


   while (i < list1.Count && j < list2.Count)
   {
      if (list1[i] == list2[j])
         return list1[i];

      if (list1[i] < list2[j])
         i++;
      else
         j++;    
   }
   return -1; // not found
}
public int-findsimilarityinsortedList(列表1、列表2)
{
int i=0;
int j=0;
而(i
n^765?这是一个很大的数字……是的。但不要拘泥于数字。我需要逻辑。这里的问题当然是内存。否则会有太多消耗内存的O(n)排序算法。2个数组可以放入内存,但3个不能?没有数组计数限制。但是数组大小非常重要。数组长度不能等于最大数。如果数组的长度为n,且最大数为n^765,则O(1)算法(可能)就足够了:对于任何n>1,两个数组包含相同数的可能性都非常接近于0。您可以在~O(1)时间内进行成员资格检查。查一下散列表。你可以用O(n)时间复杂度来确定,因为这是我要求的。哈希表也是一种很好的方法,但是我可以使用什么样的哈希算法呢。我还必须对哈希算法有个概念。因为也有人问。哈希算法肯定能解决这个问题,但它不可能是一个黑匣子:)@Pokemon:“当然,你可以用O(n)时间复杂度来完成它,因为这是我要求的。”你的推理在这里有很大的缺陷。幸运的是,你没有与教授打交道的经验,这些教授对他们正在谈论的内容一无所知。别忘了建立一个hash表@Mehrdad Afshari的成本也许很不幸,你无法解决此类问题^^。这在O(n)时间复杂度下是可能的,而不需要最大数量大小的数组。我必须弄明白:)这可以用散列方法来完成,但我也需要有那个散列方法。不仅仅是说使用散列。所以我必须解释使用了什么样的散列。不要关心位大小。我需要逻辑。@pokemoncrat:你几乎可以使用任何你想要的哈希表。它的大小应该在2*n左右。