2 solutions - Sort by Row & Visit by Row
Solution 1 Sort by Row
Initialize a list contains numRows rows. Iterate through s from left to right and add the character into appropriate row in the list. Combime the characters in each row together.
Use curRow and direction to know which row is the right one for current character.
class Solution {
public String convert(String s, int numRows) {
if(s.length()==1||numRows<2){
return s;
}
List<StringBuilder> rows = new ArrayList<>();
for (int i = 0; i < numRows; i++) {
rows.add(new StringBuilder());
}//initialize
int dir=0;//direction:down or up
int curRow=0;
for(int j=0;j<s.length();j++){
rows.get(curRow).append(s.charAt(j));
if(dir==0){
curRow+=1;
}
else{
curRow-=1;
}
if(curRow==numRows-1||curRow==0){
dir=~dir;
}
}
StringBuilder res = new StringBuilder();
for (StringBuilder row : rows) {
res.append(row);
}
return res.toString();
}
}
Complexity Analysis
Time Complexity: O(n) where n is the length of s
Space Complexity: O(n)
Solution 2 Visit by Row
Visit the characters in the same order as reading the Zig-Zag pattern line by line.
class Solution {
public String convert(String s, int numRows) {
if (s.length() == 1 || numRows < 2) {
return s;
}
StringBuilder res = new StringBuilder();
int len = s.length();
int cycle = 2 * numRows - 2;
for (int i = 0; i < numRows; i ++) {
for (int j = i; j < len; j += cycle) {
res.append(s.charAt(j));
if (i > 0 && i < numRows - 1) {//if not the first row and the last row
int k = j + cycle - 2 * i;
if (k < len) {
res.append(s.charAt(k));
}
}
}
}
return res.toString();
}
}
Complexity Analysis
Time Complexity: O(n) where n is the length of s. Each index is visited once.
Space Complexity: O(n). For the cpp implementation, O(1) if return string is not considered extra space.