简体   繁体   English

在 O(n) 中查找数组中的所有差异

[英]Find all differences in an array in O(n)

Question: Given a sorted array A find all possible difference of elements from A.问题:给定一个已排序的数组 A,找出 A 中元素的所有可能差异。

My solution:我的解决方案:

for (int i=0; i<n-1; ++i) {
  for (int j=i+1; j<n; ++j) {
    System.out.println(Math.abs(ai-aj));
  }
}

Sure, it's O(n^2), but I don't over count things at all.当然,它是 O(n^2),但我根本没有多算事情。 I looked online and I found this: http://www.careercup.com/question?id=9111881 .我在网上查了一下,发现了这个: http : //www.careercup.com/question?id=9111881 It says you can't do better, but at an interview I was told you can do O(n).它说你不能做得更好,但在一次采访中我被告知你可以做到 O(n)。 Which is right?哪个是对的?

A first thought is that you aren't using the fact that the array is sorted.第一个想法是您没有使用数组已排序的事实。 Let's assume it's in increasing order (decreasing can be handled analogously).让我们假设它是按递增顺序排列的(递减可以类似地处理)。

We can also use the fact that the differences telescope (i>j):我们还可以使用差异望远镜 (i>j) 的事实:

a_i - a_j = (a_i - a_(i-1)) + (a_(i-1) - a_(i-2)) + ... + (a_(j+1) - a_j)

Now build a new sequence, call it s, that has the simple difference, meaning (a_i - a_(i-1)) .现在构建一个新序列,将其命名为 s,它有一个简单的区别,意思是(a_i - a_(i-1)) This takes only one pass ( O(n) ) to do, and you may as well skip over repeats, meaning skip a_i if a_i = a_(i+1) .这只需通过一次( O(n) ),您也可以跳过重复,这意味着如果a_i = a_(i+1)则跳过a_i

All possible differences a_i-a_j with i>j are of the form s_i + s_(i+1) + ... + s_(j+1) .所有可能的差异a_i-a_ji>j的形式都是s_i + s_(i+1) + ... + s_(j+1) So maybe if you count that as having found them, then you did it in O(n) time.所以也许如果你认为找到了它们,那么你就在O(n)时间内完成了。 To print them, however, may take as many as n(n-1)/2 calls, and that's definitely O(n^2) .然而,要打印它们,可能需要多达n(n-1)/2调用,这绝对是O(n^2)

For example for an array with the elements {2 1 , 2 2 , ..., 2 n } there are n⋅(n-1)/2 possible differences, and no two of them are equal.例如,对于元素为{2 1 , 2 2 , ..., 2 n }的数组,有n⋅(n-1)/2 个可能的差异,并且没有两个是相等的。 So there are O(n 2 ) differences.因此存在O(n 2 )差异。

Since you have to enumerate all of them, you also need at least O(n 2 ) time.由于您必须枚举所有这些,您还需要至少O(n 2 )时间。

Yes you can surely do that its a little tricky method.是的,您当然可以这样做,这是一个有点棘手的方法。 to find differances in O(n) you will need to use BitSet(C++) or any similar Data Structure in respective language.要找到 O(n) 中的差异,您需要使用 BitSet(C++) 或相应语言中的任何类似数据结构。

Initialize two bitset say A and B You can do as follows: For each iteration through array: 1--store consecutive differance in BitSet A 2--LeftShift B 3--store consecutive differance in BitSet B 4--take A=A or B初始化两个位集,例如 A 和 B 您可以执行如下操作: 对于通过数组的每次迭代: 1--在 BitSet A 中存储连续差异 2--LeftShift B 3--在 BitSet B 中存储连续差异 4--取 A=A 或乙

for example I have given code- Here N is Size of array例如我给出了代码 - 这里 N 是数组的大小

for (int i=1;i<N;i++){
    int diff = arr[i]-arr[i-1];
    A[diff]=1;
    B<<=diff;
    B[diff]=1;
    A=A | B;
}

Bits in A which are 1 will be the differances. A 中为 1 的位将是差异。

sorted or unsorted doesn't matter, if you have to calculate each difference there is no way to do it in less then n^2,排序或未排序无关紧要,如果您必须计算每个差异,则无法在小于 n^2 的时间内完成,

the question was asked wrong, or you just do O(n) and then print 42 the other N times :D问题问错了,或者你只是做 O(n) 然后再打印 42 N 次:D

You can get another counter-example by assuming the array contents are random integers before sorting.您可以通过在排序之前假设数组内容是随机整数来获得另一个反例。 Then the chance that two differences, Ai - Aj vs Ak - Al, or even Ai - Aj vs Aj - Ak, are the same is too small for there to be only O(n) distinct differences Ai - Aj.那么两个差异,Ai - Aj vs Ak - Al,或者甚至 Ai - Aj vs Aj - Ak,相同的可能性太小,以至于只有 O(n) 个不同的 Ai - Aj 差异。

Given that, the question to your interviewer is to explain the special circumstances that allow an O(n) solution.鉴于此,面试官的问题是解释允许 O(n) 解决方案的特殊情况。 One possibility is that the array values are all numbers in the range 0..n, because in this case the maximum absolute difference is only n.一种可能性是数组值都是 0..n 范围内的数字,因为在这种情况下,最大绝对差仅为 n。

I can do this in O(n lg n) but not O(n).我可以在 O(n lg n) 但不是 O(n) 中做到这一点。 Represent the array contents by an array of size n+1 with element i set to 1 where there is a value i in the array.用大小为 n+1 的数组表示数组内容,其中元素 i 设置为 1,其中数组中有值 i。 Then use FFT to convolve the array with itself - there is a difference Ai - Aj = k where the kth element of the convolution is non-zero.然后使用 FFT 将数组与其自身进行卷积 - 存在差异 Ai - Aj = k 其中卷积的第 k 个元素不为零。

If the interviewer is fond of theoretical games, perhaps he was thinking of using a table of inputs and results?如果面试官喜欢理论游戏,也许他正在考虑使用输入和结果表? Any problem with a limit on the size of the input, and that has a known solution, can be solved by table lookup.任何对输入大小有限制的问题,并且有已知的解决方案,都可以通过查表来解决。 Given that you have first created and stored that table, which might be large .鉴于您首先创建并存储了该表,该表可能很大

So if the array size is limited, the problem can be solved by table lookup, which (given some assumptions) can even be done in constant time.所以如果数组大小有限,问题可以通过查表来解决,这(给定一些假设)甚至可以在恒定时间内完成。 Granted, even for a maximum array size of two (assuming 32-bit integers) the table will not fit in a normal computer's memory, or on the disks.当然,即使最大数组大小为2 (假设为 32 位整数),该表也无法放入普通计算机的内存或磁盘中。 For larger max sizes of the array, you're into "won't fit in the known universe" size.对于更大的数组最大大小,您将进入“不适合已知宇宙”的大小。 But, theoretically, it can be done.但是,理论上,这是可以做到的。

(But in reality, I think that Jens Gustedt's comment is more likely.) (但实际上,我认为 Jens Gustedt 的评论更有可能。)

First of all the array need to be sorted首先需要对数组进行排序

lets think a sorted array ar = {1,2,3,4}让我们想想一个排序的数组 ar = {1,2,3,4}

so what we were doing at the O(n^2)所以我们在 O(n^2)

for(int i=0; i<n; i++)
for(int j=i+1; j<n; j++) sum+=abs(ar[i]-ar[j]);

if we do the operations here elaborately then it will look like below如果我们在这里精心进行操作,那么它将如下所示

when i = 0 | sum = sum + {(2-1)+(3-1)+(4-1)}                   
when i = 1 | sum = sum + {(3-2)+(4-2)}               
when i = 2 | sum = sum + {(4-3)}

if we write them all如果我们把它们都写下来

sum = ( -1-1-1) + (2+ -2-2) + (3+3 -3) + (4+4+4 ) 

we can see that我们可以看到

the number at index 0 is added to the sum for 0 time and substracted from the sum for 3 time.将索引 0 处的数字添加到总和中 0 次,并从总和中减去 3 次。
the number at index 1 is added to the sum for 1 time and substracted from the sum for 2 time.索引 1 处的数字与总和相加 1 次,并从总和中减去 2 次。
the number at index 2 is added to the sum for 2 time and substracted from the sum for 1 time.将索引 2 处的数字添加到总和中 2 次,并从总和中减去 1 次。
the number at index 3 is added to the sum for 3 time and substracted from the sum for 0 time.将索引 3 处的数字添加到总和中 3 次,并从总和中减去 0 次。

so for we can say that,所以我们可以说,

the number at index i will be added to the sum for i time 
and will be substracted from the sum for (n-i)-1 time

Then the generalized expression for each element will be那么每个元素的广义表达式将是

sum = sum + (i*a[i]) – ((n-i)-1)*a[i];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在O(n ^ 2)中找到数组中的所有三元组 - Find all triplets in array in O(n^2) 在 O(n) 中找到重复项的数组中的和对 - Find a sum pair in array with duplicates in O(n) 如何在 O(n) 时间复杂度中找到总和为 k 的所有子数组? - How to find all subarrays with sum k in O(n) time complexity? 如何使用hashmap数据类型查找满足ab = cd且具有O(n²)时间复杂度的数组中的所有对(a,b)和(c,d) - How to find all pairs (a,b) and (c,d) in an array which satisfy ab = cd with O(n²) time complexity using a hashmap data type 查找数组在小于O(n ^ 2)内重复的次数 - Find the number of times a number is repeated in an array in less than O(n^2) 在时间〜O(N)中找到数组中的最大不可重复值 - Find max non-repeatable value in the array with a time ~O(N) 算法 - 计算O(n)中排序数组中所有相等数字对? - Algorithms - Count all pairs of equal numbers in a sorted array in O(n)? 添加一个数组的所有元素,除了索引处的元素,复杂度为 O(n) - Adding all elements of an array except the element at index with O(n) complexity 在时间复杂度 O(n) 和空间复杂度 O(1) 中查找数组中重复元素的最有效算法是什么? - What is the most efficient algorithm to find repeated elements in an array in time complexity O(n) and space complexity O(1)? 将所有x元素在O(n)时间和O(1)空间中推到数组的末尾 - Push all x element to the end of the array in O(n) time and O(1) space
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM