What is the fastest algorithm for circle shifting array for M positions?
For example, [3 4 5 2 3 1 4]
shift M = 2 positions should be [1 4 3 4 5 2 3]
.
Thanks a lot.
What is the fastest algorithm for circle shifting array for M positions?
For example, [3 4 5 2 3 1 4]
shift M = 2 positions should be [1 4 3 4 5 2 3]
.
Thanks a lot.
Set it up with pointers, and it takes almost no time. Each element points to the next, and the "last" (there is no last; after all, you said it was circular) points to the first. One pointer to the "start" (first element), and maybe a length, and you have your array. Now, to do your shift, you just walk your start pointer along the circle.
Ask for a good algorithm, and you get sensible ideas. Ask for fastest, and you get weird ideas!
This method will do this work :
This algorithm runs in O(n) time and O(1) space. The idea is to trace each cyclic group in the shift (numbered by
nextGroup
variable).If you want O(n) time and no extra memory usage (since array was specified), use the algorithm from Jon Bentley's book, "Programming Pearls 2nd Edition". It swaps all the elements twice. Not as fast as using linked lists but uses less memory and is conceptually simple.
reverseArray( anArray, startIndex, endIndex ) reverses the order of elements from startIndex to endIndex, inclusive.
Depending on the data structure you use, you can do it in O(1). I think the fastest way is to hold the array in the form of a linked list, and have a hash table that can translate between "index" in the array to "pointer" to the entry. This way you can find the relevant heads and tails in O(1), and do the reconnection in O(1) (and update the hash table after the switch in O(1)). This of course would be a very "messy" solution, but if all you're interested in is the speed of the shift, that will do (on the expense of longer insertion and lookup in the array, but it will still remain O(1))
If you have the data in a pure array, I don't think you can avoid O(n).
Coding-wise, it depends on what language you are using.
In Python for example, you could "slice" it (assume n is the shift size):
(I know that hash lookup is in theory not O(1) but we're practical here and not theoretical, at least I hope so...)
This should work to shift an arry circularly: Input : { 1, 2, 3, 5, 6, 7, 8 }; Output value present in array after the forloops : {8,7,1,2,3,5,6,8,7}