あなたはサイズの配列があるとのn ≥ 6
あなたはサイズの配列があるとのn ≥ 6
回答:
サイズnの追加の配列B
fade2blackの答えのソリューションは標準的なものですが、O (n )スペースを使用します。これを次のようにO (1 )スペースに改善できます。
This algorithm assumes the RAM machine model, in which basic arithmetic operations on O(logn)
Another way to formulate this solution is along the following lines:
This solution shows that if we replace 5 by d
There's also a linear time and constant space algorithm based on partitioning, which may be more flexible if you're trying to apply this to variants of the problem that the mathematical approach doesn't work well on. This requires mutating the underlying array and has worse constant factors than the mathematical approach. More specifically, I believe the costs in terms of the total number of values n
Start with a list of pairs, where the first pair is the range over the whole array, or [(1,n)]
Repeat the following steps until the list is empty:
Steps 1 to 6 take O(j−i)
Every pair (i,j)
Consider the work to find any one duplicate. This consists of a sequence of pairs over an exponentially decreasing range, so the total work is the sum of the geometric sequence, or O(n)
To find a tighter bound, consider the worst-case scenario of maximally spread out duplicates. Intuitively, the search takes two phases, one where the full array is being traversed each time, in progressively smaller parts, and one where the parts are smaller than nd
Leaving this as an answer because it needs more space than a comment gives.
You make a mistake in the OP when you suggest a method. Sorting a list and then transversing it O(nlogn)
In order to multiply the time complexities, you need to be using a for loop. If you have a loop of length f
So, in your case you sort in O(nlogn)
In case your curious about my claim that O(f+g)=O(maxf,g)
There's an obvious in-place variant of the boolean array technique using the order of the elements as the store (where arr[x] == x
for "found" elements). Unlike the partition variant that can be justified for being more general I'm unsure when you'd actually need something like this, but it is simple.
for idx from n-4 to n
while arr[arr[idx]] != arr[idx]
swap(arr[arr[idx]], arr[idx])
This just repeatedly puts arr[idx]
at the location arr[idx]
until you find that location already taken, at which point it must be a duplicate. Note that the total number of swaps is bounded by n
while
loop runs in constant time on average. Otherwise, this isn't a linear-time algorithm.
Subtract the values you have from the sum ∑ni=1i=(n−1)⋅n2
So, after Θ(n)
x1+x2+x3+x4+x5=σ1
Supposedly, this is no good, right? You can't possibly figure out how to break this up into 5 distinct numbers.
Ah, but this is where it gets to be fun! Now do the same thing as before, but subtract the squares of the values from ∑ni=1i2
x12+x22+x32+x42+x52=σ2
See where I'm going with this? Do the same for powers 3, 4 and 5 and you have yourself 5 independent equations in 5 variables. I'm pretty sure you can solve for →x
Caveats: Arithmetic is not really O(1). Also, you need a bit of space to represent your sums; but not as much as you would imagine - you can do most everything modularly, as long as you have, oh, ⌈log(5n6)⌉
Easiest way to solve the problem is to create array in which we will count the apperances for each number in the original array, and then traverse all number from 1
Map an array to 1 << A[i]
and then XOR everything together. Your duplicates will be the numbers where corresponding bit is off.
DATA=[1,2,2,2,2,2]
from collections import defaultdict
collated=defaultdict(list):
for item in DATA:
collated[item].append(item)
if len(collated) == 5:
return item.
# n time
collated[item].append(item)
runs in constant time. Is that really true?