ZigZag Conversion
Traverse the string one character at a time, appending each character to the builder for its current row. The row index moves down or up by one; reverse the direction when it reaches the first or last row. Reading the row builders from top to bottom produces the converted string. If there is only one row, or at least as many rows as characters, the zigzag has no diagonal movement and the input is already the result.
This simulates the zigzag directly: each character is assigned to the row it occupies
in the traversal, and appending rows in order is exactly the required readout.
For N characters, each character is appended and read once, so time is O(N).
The row builders and result use O(N) space.

[Link] https://leetcode.com/problems/zigzag-conversion/
import java.util.ArrayList;
class Solution {
public String convert(String s, int numRows) {
if (numRows == 1 || numRows >= s.length()) {
return s;
}
ArrayList<StringBuilder> rows = new ArrayList<>(numRows);
for (int row = 0; row < numRows; row++) {
rows.add(new StringBuilder());
}
int currentRow = 0;
int direction = 1;
for (int i = 0; i < s.length(); i++) {
rows.get(currentRow).append(s.charAt(i));
if (currentRow == 0) {
direction = 1;
} else if (currentRow == numRows - 1) {
direction = -1;
}
currentRow += direction;
}
StringBuilder result = new StringBuilder(s.length());
for (StringBuilder row : rows) {
result.append(row);
}
return result.toString();
}
}