给定一个大小为n的数组A,以及两个数字a和b,其中b-a + 1 = n,我需要确定A是否包含a和b之间的每个数字(恰好一次)。
例如,如果n = 4且a = 1,b = 4,那么我想看看A是否是[1,2,3,4]的重新排列。
实际上,我需要使用O(1)空间(没有哈希表)来执行此操作。
我的第一个想法是对A进行排序,但是我必须在不重新排列A的情况下这样做,这样才能解决。
我的第二个想法是通过A运行一次,将条目相加并检查它们是否在正确的范围内。最后,我必须得到正确的总和(对于a = 1,b = n,这是n(n + 1)/ 2),但这并不总能捕获所有内容,例如: [1,1,4,4,5]通过了n = 5,a = 1,b = 5的测试,但不应该。
我的唯一想法是通过数组n次,确保每次只能查看一次。有更快的解决方案吗?
答案 0 :(得分:3)
只需对您已经提到的n(n+1)/2
方法稍作修改,您就可以通过一次遍历数组来完成此操作。
为此,请遍历数组,忽略a..b范围之外的元素。对于正确范围内的数字,您需要跟踪三个值:数字的总和,数字的平方和以及数字的数量。
您可以为数字之和和平方和(以及通常的数量)预先计算正确的值。
然后将结果与预期结果进行比较。例如,考虑一下,如果您正在搜索1,2,3,4。如果仅使用数字的总和,那么[1,1,4,4]将产生正确的结果(1 + 2 + 3) +4 = 10,1 + 1 + 4 + 4 = 10),但如果你也加上正方形的总和,问题很明显:1 + 4 + 9 + 16 = 30但1 + 1 + 16 + 16 = 34。
这实际上是针对问题应用(至少非常类似于)布隆过滤器。给定一个足够大的组和一对固定的函数,会有一些不正确的输入会产生正确的输出。您可以通过增加应用的过滤器数量将这种可能性降低到任意低的值。或者,你可以设计一个不能被愚弄的自适应算法 - 随便看,如果你的输入范围是N,那么将每个数字提高到N + 1的幂可能会确保你只能得到正确的结果是正确的输入(但我承认,我并不完全确定这是正确的。)
答案 1 :(得分:0)
这是一个可能有用的O(1)空间和O(n)解决方案: -
mean
和standard deviation
if(mean1!=mean2 || sd1!=sd2) return false else true.
注意:我可能不是100%准确。
答案 2 :(得分:0)
这是一个以哈希冲突概率失败的解决方案。
采用优秀的(例如加密)哈希函数H。
Compute: xor(H(x) for x in a...b)
Compute: xor(H(A[i]) for i in 1...n)
如果两者不同,那么肯定你没有排列。如果两者相同,那么你几乎肯定会得到一个排列。通过在哈希中包含随机种子,您可以对已经选择的输入产生哈希冲突的免疫。
这显然是O(b-a)的运行时间,需要O(1)外部存储,并且实现起来很简单。