2

I want to solve this problem:

For a given sequence, a[0], a[1], a[2],..., a[n-1], please find "period" of the sequence.
The period is the minimum integer k (k >= 1) that satisfies a[i] = a[i+k] for all valid i, and also k is a divisor of n.

My current solution is calculating all divisor of n (this is k) and test for all k, but it takes O(n * d(n)). I think it is slow.
Is there any efficient algorithm?

square1001
  • 1,402
  • 11
  • 26
  • 1
    You could exclude some of the divisors with O(1) rather than O(n). If a[0] !== a[1] you exclude divisor 1. If a[0] !== a[2] you exclude divisor 2. If a[0] !== a[3] you exclude divisor 3 etc. In general if a[0] !== a[divisor] you can exclude divisor from potential solutions. – Freeman Lambda Apr 28 '17 at 11:06
  • @FreemanLambda but that test can pass even if the tested divisor isn't the period, so I disagree that it's O(1). It *might* reject the divisor in one step, but it can also be much later. – harold Apr 28 '17 at 11:09
  • @harold what you say is true, but in his current solution square1001 is always testing every divisor (until solution found). Assuming that there is already a loop in place that finds all divisors of n, it shouldn't be that costly to just sneak in the a[0] !== a[divisor] in that loop. – Freeman Lambda Apr 28 '17 at 11:13

1 Answers1

5

Apply Z-algorithm ( here and here) to given sequence.

Then find the first position i such that

  i+z[i] = n

and

  n mod i = 0

If such value of i exists, it is the shortest period

MBo
  • 77,366
  • 5
  • 53
  • 86