Microsoft面试问题
从字符串中删除重复项,不使用HASHMAP和O(n)时间复杂度
O(n 2 )时间复杂度有一个解决方案,但面试问题特别提到没有HASHMAP和O(n)时间。
任何指针都很受欢迎,因为我不能想到任何低于O(n log n)时间的东西,它采用排序并使用O(n)空间。
答案 0 :(得分:11)
你做了一种斗式排序。
我们使用这样的2个数组的唯一原因是因为你明确禁止哈希映射。您可以随意代表这种结构。如果允许将字符转换为int
s,则只需使用1个数组。
由于我们假设可能的字符数量有限,因此每个数组的大小都是常数,或 O(1)
count
增加char
。如果count已经大于0
,那么您发现了重复。在char数组中搜索特定字符需要 O(1)时间,因为字符数量有限。
你将进行n次搜索,净运行时间为 O(n)
如果数组不好,那么您可以使链接列表仅保留您找到的值。它仍然是常量,因为链表的大小仍然受可能字符数的限制。
如果你这样做,你或多或少会做同样的事情,除了它在外观上看起来不像桶式排序策略。
答案 1 :(得分:3)
我可能有另一个解决方案,我认为它更糟糕,但它适用于小字符数组。算法如下:
- 我们将每个字母分配给从2开始的素数。 - 这将是我们的查找表。
- 我们找到了所有数字的乘积。 - >为O(n)
- 在循环中 - > O(n)我们检查产品%k * k == 0如果是,我们发现了重复的k。
醇>
此解决方案仅存储1个数字,但很容易溢出。主表将占用很多空间。
编辑: 如果我们添加一个只有40个唯一字符可用的约束,我们可以使用Euler的二次多项式来找到素数。
P(n)= n * n - n + 41
除了产品之外,这不需要任何额外的空间。
答案 2 :(得分:0)
traverse the list for i= 0 to n-1 elements
{
check for sign of A[abs(A[i])] ;
if positive then
make it negative by A[abs(A[i])]=-A[abs(A[i])];
else // i.e., A[abs(A[i])] is negative
this element (ith element of list) is a repetition
}
您可以在阵列中轻松将其修改为0。如果是字符,您可以使用其整数代码。