I always believe that being able to understand and express white is two different realms. If you say you understand a problem, but you cannot explain it, in my eyes, there is a fact that you have not really understood. Of course, this situation also exists, that is to say, it is a clear explanation, but it may not be true. This is what I am worried about, so please read all of myArticleMy friends pointed out the errors in my article. Thank you ......
1. Problem definition
DesignAlgorithmAnd shifts the right K-Bit of an array A contains n elements. The time complexity is O (n. An example shows the effect of the algorithm: the element contained in the array is 123456, And now it needs to be shifted to 2 places by two places to the right of the loop.
2. Solution
2.1 simple ideas
This is often the case. Although a simple idea cannot meet the requirements of a question, it may indeed be the basis for optimization. The simple solution to this problem is that the complexity of right shifting and right shifting is O (n) each time. This operation is performed K times, therefore, the time complexity is O (n * K ). But now you know that you want to move the number k to the right, it seems a bit dumb if you want to move the number one step further. Why not?
2.2 space change time
For algorithm optimization, changing the space for time is a conventional method. You can use an auxiliary array tTheThe elements in the n-k + 1 to n-bit arrays are stored in T, and then the elements in array a areThe1 to n-k array elements are stored in the secondary array T, and then the elements in array t are copied back to array A. This completes the round-robin right shift of the array, the time complexity is O (n), but it increases the space complexity of O (n. What if you require a maximum of two auxiliary spaces? This requires us to think about further optimization.
2.3 optimize with "flip"
Consider the situation where element 123456 in array a shifts two places to the right in a loop !!! Can this be achieved? Divide array a into two parts: a [0 ~ N-k-1] And a [n-k ~ N-1], flip the two parts separately, and put them together in reverse order ). Specifically:
(1) Flip 1234: 123456 ---> 432156
(2) Flip 56: 432156 ---> 432165
(3) Flip 432165: 432165 ---> 561234
Let's take a look. The flip operation has been completed. Now let's take a look.Code(Relatively simple ):
1 // Reverse Order 2 Void Reverse ( Int A [], Int B, int e) 3 { 4 For (; B <E; B ++, e -- ) 5 { 6 Int Temp =A [B]; 7 A [B] = A [E]; 8 A [e] = Temp; 9 } 10 } 11 // Shift right of Loop 12 Void Rightshift ( Int A [], Int ,Int N, Int K) 13 { 14 Reverse (, 0 , N-k- 1 ); 15 Reverse (A, n-k, n- 1 ); 16 Reverse (, 0 , N- 1 ); 17 }
Now we can analyze the time-space complexity. The time complexity is obviously O (N), mainly to complete the flip (reverse) operation, and only one auxiliary space is used. Obviously, this is a good algorithm...
Note:
Careful readers may find that the right shift here is not less than N, so a k> N will cause problems. After a simple analysis, we found that if a [] = {1, 2, 3, 4, 5, 6} and the array length is 6, the 7-bit right shift of the loop is the same as that of the 1-bit right shift of the loop, therefore, you only need to set K in the rightshift () function to k = K % N. This solves the problem.
Let's take a look at some of the lessons learned.