" Questions Eyes " Leetcode (6 ) : ZigZag Conversion
url:https://leetcode.com/problems/zigzag-conversion/
Description
The string is "PAYPALISHIRING"
written with a zigzag pattern on a given number of rows like this: (You may want to display this pattern In a fixed font for better legibility)
P A H NA p L S i i GY i R
And then read on line:"PAHNAPLSIIGYIR"
Write the code that would take a string and make this conversion given a number of rows:
String convert (string text, int nRows);
convert("PAYPALISHIRING", 3)
should return "PAHNAPLSIIGYIR"
.
"Chinese description" gives a string such as "paypalishiring", which requires returning the result of a line output after zigzag. For example, the result above is from the first line Pahn, to the second row Aplsiig, to the third row Yir end. So the final output is: "Pahnaplsiigyir".
————————————————————————————————————————————————————————————
"Initial thinking"
Just started to see 10 minutes did not read the topic, Khan ~ ~ ~
Later I wrote a, a mention staggered, read the next test case, just understand why.
In fact, the so-called zigzag means, your input string, from the top down to write a column, and then from the bottom to the right to write a slash, and then write down the vertical, then to the right, so repeated, as shown.
Then, Brute wrote a, thought is directly hard according to the law to find the position from the string to pick characters out of the spell.
The process is very depressed, because the first two lines of special consideration, the middle row and find the law, looking for a long time did not find out why. Finally, the front just wrote a program out, it is difficult to read. :
1 PublicString Convert (String s,intnumrows) {2 if(NumRows = = 1 | | numrows >=s.length ()) {3 returns;4 }5StringBuilder SB =NewStringBuilder ();6 intLength =s.length ();7 intr = length% (2 * numRows-2);//Total remain number, indicate so how many rows need to add more element8 intc = Length/(2 * numRows-2);//Columns number9 intExcol = 0;Ten intremain = 0;//Total Remain-numrow = remain One if(R >=numrows) { AExcol = 1; -remain = R-NumRows; -}Else { theExcol = 0; -remain =R; - } - + for(inti = 0; i < numrows; i++) { - if(i = = 0) { + for(intj = 0; J < C + (R > 0? 1:0); J + +) { ASb.append (S.charat ((2 * numRows-2) * j +i)); at } -}Else if(i = = NumRows-1){ - for(intj = 0; J < C + Excol; J + +) { -Sb.append (S.charat ((2 * numRows-2) * j +i)); - } -}Else { in intj = 1; - Sb.append (S.charat (i)); to while(J * (2 * numRows-2)-i <length) { +Sb.append (S.charat (J * (2 * numRows-2)-i)); - if(J * (2 * numRows-2) + i <length) { theSb.append (S.charat (J * (2 * numRows-2) +i)); * } $J + +;Panax Notoginseng } - } the } + returnsb.tostring (); A}
Convert
Reflection
Then saw the online god of Thought (Khan, easy problems can not get out ...) ), enlightened, consider such as (forgive me, lazy to paint with Photoshop):
Clearly, the first-eye rule is that there is a cyclic cycle (separated by a dashed line), which is the cycle = 4 when numrow=3. For example, the entire string is divided into 4 cycle (last dissatisfaction, discussed later).
It is clear, then, that the characters from any one cycle to the next cycle will have to jump to the same position. For example, the first character, p, is the second character of the first line, a, and a skip cycle character is required. So the position of a is 0 + cycle = 4.
Here, the two lines have been basic analysis finished. Calculates the cycle number, takes I as the line number, and then loops through the k in each row, outputting the character of the K + cycle position (if this position is less than the string length).
The practical difficulty of this problem lies in the search for the law of the middle line of Z-word. Find the solve, you can not find it slowly positive code bar. This is the reason why this problem is easy, and I think it is very boring reasons ...
Or look at the above picture, the middle behavior "Aplsiig", what is the law of this line?
We can see that each cycle of this line actually has 2 characters (except for the last not full cycle): Ap/ls/ii. This is a very important discovery:
First of all, no matter how much numrows, this law is unchanged;
Second, the first character jumps from the 2 characters to the first character of the next 2 characters, and the number of hops is also cycle. For example, a to L on the figure is actually the position of a +cycle = L.
Well, if we put this line into the first and the top two lines of the loop, we can easily find all the 2 character group of the initial character, we call the 2 character group the first character position is J, where the line number is I, there are the following rules:
j = i + cycle * k, k = 0, 1, 2, 3, ...
You can also see that for the middle row, for each k in the loop, look for 2 characters. Find J at the same time, find the second character position Second_j, has been circulating to the end, this line does not output it?
So what's the rule of Second_j?
For NumRows ==3, the law of Aplsiig seems simple, because their position is: 1, 3, 5, 7, 9, 11, 13. So Second_j = j + 2?, let's check it out.
Assuming numrows==5, then the zigzag result of the topic string should be:
P H A S i Y i R
P L I G
A
For example, for I=1 (the second line), the first cycle of J=1,second_j = 7. For i=2, the first cycle of the j=2, and Second_j = 6. It is clear that the above conclusions are wrong.
We can observe that the greater the I, the smaller the gap between Second_j and J. Therefore, it can be assumed that Second_j = n-c * I. N is a number, and C should be the coefficient of I. It is also obvious to guess that N should be a linear function of J. Then we assume that n = a * j + B.
So, get the equation: Second_j = A * j + b-c * I. Next, let's try to solve this equation group.
According to the above position number (1-7, 2-6, 3,5), substituting Second_j, J, I, respectively, to obtain the following equation group:
A * 1 + b-1*c = 7
A * 2 + b-2*c = 6
A * 3 + b-3*c = 5
The above three can be easily calculated, B = 8, and a-c =-1. Continue, according to the above numbers (3-5, 11-13) The following equations are solved:
11*a + 8-3c = 13
3*a + 8-3c = 5
Solution A = 1, c = 2
Thus, get Second_j = j + 8-2 * I.
Back to NumRows = 3, Second_j = j + 8-2*i, let's verify: 3 = 1 + 8-2*1. This is obviously wrong, where is the problem?
Think about, A is the parameter of J, C is the parameter of I, the parameter will not change with the numrows change, they must be fixed. The only variable is only B. Then in the numrow=5 time, b=8, in numrows=3 time, b=4, the above formula can be set up.
Here we find the law of B, B = cycle!!!
So, Second_j = j + cycle-2* I. On behalf of the above various conditions to verify that all validation success!
In this way, we have the relationship between Second_j and J, then for each row I, K is the loop variable, each cycle of the first character position is J, the second position is Second_j = J * cycle-2 * i.
The code calls out!
"Show me the code!!! 】
1 if(NumRows <= 1)returns;2StringBuilder SB =NewStringBuilder ();3 //The size of a cycle (period)4 intCycle = 2 * numRows-2;5 for(inti = 0; i < numrows; ++i)6 {7 for(intj = i; J < S.length (); j = j + cycle) {//j = j + cycle is wonderful!!!8 Sb.append (S.charat (j));9 intSecondj = (j-i) + Cycle-i;Ten if(I! = 0 && I! = numRows-1 && Secondj <s.length ()) One sb.append (S.charat (SECONDJ)); A } - } - returnSb.tostring ();
Convert
In addition, it should be seen that the two lines can be integrated into the overall consideration. When i = 0 or i = numrows, do not consider second_j, because they do not. So, the inner-for cycle always keeps jumping J + Cycle
In addition, Second_j must check to see if it is out of bounds.
Finally, I would like to say that this problem is very boring ~ ~ ~
Leetcode (6): ZigZag Conversion