Many cool people have discussed this issue, and my work is also from this blog by July.
Http://blog.csdn.net/v_july_v/article/details/6322882.
My blog is on the shoulders of giants, not pirated! There are two reasons for writing this blog post: First, it seems complicated because it is difficult for the original blog post to finish reading it without patience. As a matter of fact, I have finished reading the code based on my own ideas. This is my own idea. Code is the implementation details. As long as the idea of the algorithm is clear, the implementation of the code is no problem. So adhering to this idea, I will not post code in this blog post and sort out the algorithm ideas from the beginning to the end, but it is not guaranteed that the Code will not be added in future updates. Another reason is that the problem is indeed worth thinking about. It is of great significance to think about different ideas and practices. Based on the above two points, I wrote this blog post.
Problem definition
For a string with the length of N, we need to move the M bit left in a loop. For example, if ABCDE is used, the result of the two shifts left of the loop is cdeab. This problem must be solved within the time complexity of O (N) and the space complexity of O (1.
For a string with the length of N, if we shift n places left, the result is the original string, So we m = m % N, there is no problem with this. Next, if we are dealing with the right-shifting m' bit (m' <n), then we correspond to the left-shifting N-m' bit, which makes it easy to know why it is correct, no explanation is added here. Next we will focus on how to solve the left-shift Problem of a string.
How to use string flip
Obviously, if we move ABCDE two places to the left, the result is cdeab. In fact, we can see that it is equivalent to moving the first two places directly to the back of the original string.
Therefore, it is easy to think that we should first flip the entire ABCDE to get edcba, and then flip the subsequent M bit separately to get edcab, and then flip the previous (n-m) bit to get the cdeab. As a result, we can clearly find a solution to this problem through flip.
For a program with a given string being reversed, we consider it as the space complexity of O (1). Then the time complexity of the entire method is strictly O (2n ), I think this method is quite good.
Solve this problem recursively
Let's also take the example of ABCDE shifting two places to the left. The result is cdeab. We found that we only moved AB to the end of the string as a whole. Therefore, we try to directly move the first M bit to the target location to get the decab. We find that the first 3 bits are Dec, and only the left shifted two bits are the correct results. Therefore, it is not difficult to find that this problem can be solved by recursion.
In addition, when m> (n-m), for example, ABCDE shifts three places to the left, we first move the first two places to the target location to get decab, obviously, we only need to move the three digits to the left one. Therefore, we know that when m> (n-m), we exchange the preceding (n-m) bits with the following (n-m) bits, then, move the rear M bit of the string to the left (m-(N-m.
In fact, the above two situations are the same. They both exchange the first M bit of the string with the M bit at the end of the string, but because of the actual situation, they are divided into the above two directions.
Recursive methods should be said to achieve strict O (n) complexity, but we know that recursion requires the system to automatically maintain the stack, therefore, we reserve opinions on the resources consumed by this solution.
Use mathematics to solve the problem
In fact, the first thought of this question is to replace the current bit with the one corresponding to the Left shift M bit, and then replace it in sequence. Later, we found that in some cases, the entire string can be moved left after a loop replacement, and in some cases there will be multiple loop chains. At the moment, we can only get the regular pattern, and we cannot think of a good way to prove it, I can't blame the previous elementary number theory!
We found that for a string with a length of N, moving m to the left will form a gcd (n, m) chain. Here, gcd is the well-known maximum common approx, the length of each chain is obviously N/(gcd (n, m )). How can we prove this problem? We place I + J * m and I + K * m in a circle and point to the same element, then (I + J * m) % N = (I + K * m) % N, so we know n | (k-j) * m according to the same remainder, while n
= N' * gcd (n, m), M = M' * gcd (n, m ). So we get 'n' | (k-j) * M'. Because n' and M' are mutually unique, n' | (k-j ), therefore, we know the minimum K-j = n' = N/gcd (n, m), that is, there are N/gcd (n, m) elements in a loop chain, therefore, there are a total of gcd (n, m) cycle chains. Therefore, we only need to take the first gcd (n, m) elements, each taking a chain to replace the loop. In fact, this algorithm is optimal, with real O (n) time complexity and no additional overhead.
Postscript
You may have discovered that I didn't mention the double pointer method mentioned in the connection blog here, because the worst case is O (n ^ 2) the tragic fate. For example, if a string with a length of 2k-1 is left shifted to k bits, we need to move the following (k-1) bits forward to k bits one by one, obviously, the time complexity is K * (k-1), where k is n/2, so the approximate complexity is O (n ^ 2. We can see why this is the case, because the method finally needs to move each character m times one by one when the remaining number of characters is smaller than m, which increases the complexity of the algorithm.
In fact, the three ideas mentioned above have already been excellent. It is good to think of three methods to solve a problem. Here, I would like to express my admiration for July. Here is a general summary of the content in the original blog. If you want to read the code and more detailed content, you can go to the link blog at the beginning to learn.
In addition, if the reader finds that there is a problem in this article and hopes that the cool will not be enlightened, I should listen carefully to the teachings.
I wish you a happy new year and a new year.