之前认为这题太笨比,然后华为面试没撕出来,自己更笨比。然后今天写的时候还写了好久。
public String convert(String s, int numRows) {
if (s.length() <= numRows) {
return s;
}
if (numRows == 1)
return s;
//一个周期2 * numRows - 1
int unit = 2 * numRows - 2;
int column = s.length() / unit;
if (s.length() - column * unit > numRows) {
column = column * (numRows - 1) + s.length() - column * unit - numRows + 1;
} else if (s.length() == column * unit){
column = column * (numRows - 1);
} else {
column = column * (numRows - 1) + 1;
}
char[][] arr = new char[numRows][column];
int index = 1;
while (index <= s.length()) {
//定位column;
int columns = index / unit;
if (index - columns * unit > numRows) {
columns = columns * (numRows - 1) + index - columns * unit - numRows;
} else if (index == columns * unit){
columns = columns * (numRows - 1) - 1;
} else {
columns = columns * (numRows - 1);
}
//定位row
int row = index % unit;
if (row > numRows) {
row = numRows - (row - numRows) - 1;
} else if (row > 0){
row = row - 1;
} else {
row = 1;
}
arr[row][columns] = s.charAt(index - 1);
index++;
}
StringBuilder sb = new StringBuilder();
for (char[] chars : arr) {
for (char c : chars) {
if (c != '\u0000')
sb.append(c);
}
}
return sb.toString();
}
标准做法:根据字符的下标确定字符位于Z字形图案的哪一行,注意,根本不需要知道字符在哪一列其实。用一个StringBuilder列表实现即可。笨比的不是题目,是我。
class Solution {
public String convert(String s, int numRows) {
if (numRows == 1) return s;
List<StringBuilder> rows = new ArrayList<>();
for (int i = 0; i < Math.min(numRows, s.length()); i++)
rows.add(new StringBuilder());
int curRow = 0;
boolean goingDown = false;
for (char c : s.toCharArray()) {
rows.get(curRow).append(c);
//每次行号都会加1或者减1,有两个转折点,就是curRow = 0的时候和curRow=numRows-1的时候,会由加一变为减一,或者由建议变为加一
if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
curRow += goingDown ? 1 : -1;
}
StringBuilder ret = new StringBuilder();
for (StringBuilder row : rows) ret.append(row);
return ret.toString();
}
}