Dutch flag question

The picture above is a Dutch flag. From the picture we can clearly see its characteristics. It consists of three areas, namely red, white and blue.

OK, now our problem is out. Now we have a table in front of us, and the red, white and blue lines are neatly placed on the table, but their order is messy.

Our requirement is: use an algorithm to pick out these lines and rearrange the order. The final result is like the Dutch flag in the picture above, with red on top, white in the middle, and blue on the bottom.

 Well, how do we achieve the above problem? In fact, everyone who gets this question must have an algorithm in their mind, namely:

①: Use a variable to identify the position of the array we want to put (using an array to simulate a table), initialize it to 0, and then increment it in turn. We just need to traverse the entire array, find the red line (the red, white and blue lines we can simulate with 0, 1, 2), and if found, swap it with the line that identifies the position. When there is no red line in the array after the identification, look for the white line. After the white line is found, the rest must be the blue line. At this point our entire algorithm is over.

Let's look at this algorithm:

An algorithm that is easy to think of, but also a very complicated algorithm, we can see that its time complexity is O(N*M);

It is true that such an algorithm is not easy to accept in terms of speed. Let's look at another algorithm:

②: We first divide the entire array into 3 areas, namely red area, white area, blue area, and then first we traverse the red area to determine whether the value of the current cell is red, if it continues to traverse, otherwise determine whether the value is white or not Blue, if it is white, go to the white area to find a red unit to exchange with it, otherwise go to the blue area to find a value to exchange with it. When the red area traversal is completed, we then traverse the white area. If the current cell is not white, it must be blue, and we go to the blue area to find a value to exchange with it. When the blue area traversal is complete. Our work is done.

Let's look at the code:

There is a flaw in this method, I don't know if you have found it. It handles one less case, that is: if the white area has no red or the blue area has no red, the algorithm does not handle this situation, and if it is not found in one of the areas, it should go to the other area. to find.

This method, if in general, is much faster than the first algorithm, because it reduces a lot of unnecessary exchanges, and in the special case that is missed above, each exchange of it is a necessary exchange. But the time complexity of this algorithm is still a bit high, it should still be O(M*N);

Let's analyze the above algorithm. Before we exchange, we need to traverse a part of the array to find. This aspect wastes time and affects our speed. We can come up with a method of changing space for time. Let's look at another algorithm.

③: We first define three arrays to save the position of the red part of the white area, the red part of the blue area and the white part of the blue area. Then define three variables to identify the positions where the three arrays are swapped. At the beginning of the algorithm, we start to traverse the white area, and the blue area assigns values ​​to these three arrays. After that, we can traverse the red area and the white area in turn according to the above method. After finding it, we only need to exchange the position in the corresponding array with it.

Let's look at the algorithm:

Let's see that the complexity of this algorithm is already O(N); hehe. However, we spent a certain amount of space resources for this. Efficiency is traded for space. Of course there are other better ways, when I believe O(N) complexity is already the fastest. But I believe there are simpler algorithms. As long as we are willing to think, miracles will always happen. .