Landlord again to ~ (≧▽≦)/~, scientific research, is to so bang. In fact, the old line of the landlord is the formula Ah, do these algorithms, in fact, the landlord in the lazy. Well, say no more, please come out of our protagonist today! or the array-loop shift.
Let's look at the requirements of the topic below.
Title Requirements:
Design an algorithm that shifts the array of n elements to the right by the K-bit, requiringComplexity of TimeFor O(N) , and only allow the use oftwo additional variables。
Topic answer
Let us give an example to help ourselves to think. The array is [1, 2, 3, 4, 5, 6, 7, 8], with a cyclic shift of 4 times.
Original sequence: [1, 2, 3, 4, 5, 6, 7, 8]
Shift Right 1 bits: [8, 1, 2, 3, 4, 5, 6, 7]
Shift Right 2 bits: [7, 8, 1, 2, 3, 4, 5, 6]
Shift right 3 bits: [6, 7, 8, 1, 2, 3, 4, 5]
Shift Right 4 bits: [5, 6, 7, 8, 1, 2, 3, 4]
Solution One: Time complexity O (N * K)
Code:
#include <iostream>#include <vector>using namespace STD;voidGetshiftarray (int*parray,intLenintK);voidPrintArray (int*parray,intLen);intMain () {intA[] = {1,2,3,4,5,6,7,8};intLen =sizeof(a)/sizeof(int);intK =4; Getshiftarray (A, Len, K); PrintArray (A, Len); System"Pause");}voidGetshiftarray (int*parray,intLenintK) {intEndtemp =0; while(k--) {endtemp = Parray[len-1];//Save the last element of the array for(intn = len-1; N >=0; n--) {Parray[n] = parray[n-1]; } parray[0] = endtemp; }}voidPrintArray (int*parray,intLen) { for(inti =0; i < Len; i++) {cout<< Parray[i] <<" "; }cout<< Endl;}
This solution is not in line with the problem of linear complexity requirements.
But we're going to be aware of a problem here, what if k > n? We can experiment with an array that shifts n times, and the array returns to its original appearance. So when k> N, it just needs to be shifted to the right k-n times. In general, no matter what the value of K, then all only need to move to the right to shift K N times, then the above code only need to change a little bit, the complexity of time can be changed to < Span class= "Mrow" id= "mathjax-span-167" > o ( n ? N ) , although it still does not meet the requirements, but we look at the following code:
#include <iostream>#include <vector>using namespace STD;voidGetshiftarray (int*parray,intLenintK);voidPrintArray (int*parray,intLen);intMain () {intA[] = {1,2,3,4,5,6,7,8};intLen =sizeof(a)/sizeof(int);intK = A; Getshiftarray (A, Len, K); PrintArray (A, Len); System"Pause");}voidGetshiftarray (int*parray,intLenintK) {intEndtemp =0; k = k% Len; while(k--) {endtemp = Parray[len-1];//Save the last element of the array for(intn = len-1; N >=0; n--) {Parray[n] = parray[n-1]; } parray[0] = endtemp; }}voidPrintArray (int*parray,intLen) { for(inti =0; i < Len; i++) {cout<< Parray[i] <<" "; }cout<< Endl;}
Solution Two: Linear time
In fact, carefully found out, [1, 2, 3, 4, 5, 6, 7, 8] can be divided into two parts, not bold for the first part, Bold is the second part. If the array is shifted to the right by 4 times, the internal order of the two parts is unchanged, but only two parts are exchanged. Then we can follow the following process to complete the cyclic shift ( oh, God, how did you figure that out?) ).
Original sequence: [1, 2, 3, 4, 5, 6, 7, 8]
Reverse the first half: [4, 3, 2, 1, 5, 6, 7, 8]
Reverse the second half: [4, 3, 2, 1, 8, 7, 6, 5]
Reverse the entire sequence: [5, 6, 7, 8, 1, 2, 3, 4]
Look at the code, it's so simple.
#include <iostream>#include <vector>using namespace STD;voidGetshiftarray (int*parray,intLenintK);voidPrintArray (int*parray,intLen);voidReversearray (int*parray,intStartintEnd);intMain () {intA[] = {1,2,3,4,5,6,7,8};intLen =sizeof(a)/sizeof(int);intK = A; Getshiftarray (A, Len, K); PrintArray (A, Len); System"Pause");}voidGetshiftarray (int*parray,intLenintK) {k = k% Len;//First half reverseReversearray (Parray,0, Len-k-1);//Reverse Half partReversearray (Parray, len-k, Len-1);//Whole sequence reverse orderReversearray (Parray,0, Len-1);}voidReversearray (int*parray,intStartintEnd) { for(; start < end; start++, end--) swap (Parray[start], parray[end]);}voidPrintArray (int*parray,intLen) { for(inti =0; i < Len; i++) {cout<< Parray[i] <<" "; }cout<< Endl;}
haha haha, have you got it? Landlord application column to go! If you also want to learn the algorithm, then can and landlord together, ah, a lot of exchanges, refueling refueling (^ω^)
The beauty of programming 6: Array loop shift