题目地址:Z 字形变换
描述:
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISH” 行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESEDH”。
Example 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
第一种:自己写的,时间复杂度O(n^2),首先是选择最上层作为节点,第一层循环是向下计数,第二层循环是向左进行节点的循环。
第二种是官方写的,时间复杂度是O(n),而且思路很简单,效率高。
import java.util.ArrayList;
import java.util.List;
/**
* z-convert
*/
public class Solution {
/**
* A G M
* B F H L N
* C E I K O
* D J P
* <p>
* A E I M
* B D F H J L N P
* C G K O
*
* @param args
*/
public static void main(String[] args) {
// 03 415 627
String src = "ABCDEFGHIJKLMNOP";
// String convert = convert(src, 5);
String convert = officialConvert(src, 5);
System.out.println(convert);
}
//0-6-12-18 /4 自己写的,时间复杂度O(n^2)
private static String convert(String string, int numRows) {
//首先找规律,以最上面的值作为节点
int len = string.length();
//找出节点的个数
int nn = (len - 1) / (numRows - 1) / 2;
//每个节点的长度
int node = (numRows - 1) * 2;
StringBuffer res = new StringBuffer();
int n = 0;
//外层循环是向下的次数
while (n < numRows) {
res.append(string.charAt(n));
int i = 1;
//内层循环是向右的次数,判断会比实际的多一层,补全三角,以免遗漏
while (i < nn + 2) {
//numRows-1指的是最后一层的下标和n=0的作用一样都是去重
if (n != numRows - 1 && node * i - n < len) {
res.append(string.charAt(node * i - n));
}
if (n != 0 && node * i + n < len) {
res.append(string.charAt(node * i + n));
}
i++;
}
n++;
}
return res.toString();
}
//官方提供的
private static String officialConvert(String s, int numRows) {
if (numRows == 1) return s;
List<StringBuilder> rows = new ArrayList<StringBuilder>();
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);
goingDown = extracted(numRows, curRow, goingDown);
curRow += goingDown ? 1 : -1;
}
StringBuilder ret = new StringBuilder();
for (StringBuilder row : rows) ret.append(row);
return ret.toString();
}
private static boolean extracted(int numRows, int curRow, boolean goingDown) {
if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
return goingDown;
}
}
``