非常困难的排序算法问题 - On)时间 - 时间复杂度

时间:2010-12-17 12:21:36

标签: algorithm sorting time-complexity

由于问题很长,我无法在标题处描述。

想象一下,我们有2个未排序的整数数组。两个数组长度都是n,并且它们包含0到n ^ 765之间的整数(n最大功率765)。

我想比较两个数组,并确定它们是否包含任何相同的整数值,而且时间复杂度为O(n)。

在同一个数组中不可能重复

感谢任何帮助和想法。

4 个答案:

答案 0 :(得分:6)

你想要的是不可能的。每个元素将以最多log(n ^ 765)位存储,即O(log n)。因此,简单地读取两个数组的内容将需要O(n * logn)。

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

修改

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

答案 1 :(得分:1)

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

答案 2 :(得分: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)。

现在你可以把Numbers(i)写成数组:Nembers(i)=(A0,A1,...,A765)并知道你可以对基数进行排序:

首先比较所有A765,然后......,所有Ai都在0..n范围内,所以为了比较Ai,你可以使用Counting sort(计数排序是O(n)),所以你的基数sort是O(n * 765),即O(n)。

基数排序后你有两个排序数组,你可以在O(n)中找到一个相似的项目,或者使用merge algorithm(比如合并排序)来找到最可能的相似性(不只是一个)。

如果输入项的大小是O(n ^ C),则可以在O(n)中排序(C是固定号)。但是因为这种排序方式的开销很大,所以更喜欢使用quicksort和类似的算法。这个问题的简单示例可以在Introduction to Algorithm书中找到,该书询问数字是否在范围(0..n ^ 2)范围内如何在O(n)中对它们进行排序。

编辑,了解如何在2个排序列表中找到类似的项目:

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

它就像下面这样简单:

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
}

答案 3 :(得分:-1)

我认为你不能做到O(n)。 你应该检查n值是否在另一个数组中。这意味着至少在另一个数组只有1个元素的情况下,你有n个比较操作。但是,由于你有另一个数组的n元素,你可以只做O(n * n)