6. N 字形变换
- 题目描述
- 解题思路
- Code1
- Code2
- Code3
题目描述
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,输出:"PAHNAPLSIIGYIR"。
比如输入字符串为 **"PAYPALISHIRING"** 行数为 **4** 时,排列如下
P I N
A L S I G
Y A H R
P I
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,输出:"PINALSIGYAHRPI"。
若s = "A", numRows = 1,那么输出 **"A"**
解题思路
根据题意可知,我们要遍历整个字符串,然后将其“拼装”为一个Z字型。 那么,在执行拼装操作时,其实就是一个“从上向下”,当长度达到numRow的时候,在执行反方向的“从下向上”。
那么,对于每层的元素,我们可以通过StringBuilder数组进行保存,那么对应数组存储的下标index,我们需要一个boolean变量reverse,当它为false的时候,index执行加1操作,当它为true时,index执行减1操作。当所有字符串s都遍历并存储到StringBuilder数组之后,我们再执行最后结果拼装即可。具体操作如下所示:
Code1
public static String convert(String s, int numRows) {if (numRows == 1 || s.length()<=2) return s;StringBuilder[] str_arr = new StringBuilder[numRows];for (int i = 0; i < numRows; i++) {str_arr[i] = new StringBuilder();}boolean flag = true; // 当flag为真时,数值升序。反之则是降序int index = 0;for (int i = 0; i < s.length(); i++) {str_arr[index].append(s.charAt(i));if (index == 0) flag = true;if (index == numRows-1 ) flag = false;index = flag ? index + 1 : index - 1;}String res = "";for (StringBuilder a: str_arr) {res += a;}return res;
}
str_arr 也可以这么定义
String[] str_arr = new String[numRows];
for (int i = 0; i < numRows; i++) {
str_arr[i] = “”;
}
那么数组里字符的拼接就可以直接加 str_arr[index] += s.charAt(i);
上述代码的核心是这个下标升序和降序的过程
int[] num_arr = new int[s.length()];
boolean flag = true; // 当flag为真时,数值升序。反之则是降序
int index = 0;
for (int i = 0; i < s.length(); i++) {num_arr[i] = index;if (index == 0) flag = true;if (index == numRows-1 ) flag = false;index = flag ? index + 1 : index - 1;
}
System.out.print(num_arr);// (14) [0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1]
Code2
下标的升降,也可以用变量n,然后求余数来控制。
int[] num_arr = new int[s.length()];
int n = 2 * numRows - 2;
int index;
for (int i = 0; i < s.length(); i++) {index = i % n;if (index >= n - index) {num_arr[i] = n - index;} else {num_arr[i] = index;}
}
System.out.print(num_arr);// (14) [0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1]
Java代码就不写了,这回改用python。不为别的,就为简洁。
def convert(s, numRows):if numRows == 1: return sres, n = [''] * numRows, 2 * numRows - 2for i, c in enumerate(s):res[min(idx := i % n, n - idx)] += creturn ''.join(res)
Code3
核心算法,还是熟悉的样子
int[] num_arr = new int[s.length()];
int index;
for(int i=0;i<s.length();i++){index = i % (numRows*2-2);if(index >= numRows) index=(numRows-1)-(index-numRows+1);num_arr[i] = index;
}
System.out.print(num_arr);// (14) [0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1]
public static String convert(String s, int numRows) {if (numRows == 1 || s.length()<=2) return s;String[] str_arr = new String[numRows];for (int i = 0; i < numRows; i++) {str_arr[i] = "";}int index;for(int i=0;i<s.length();i++){index = i%(numRows*2-2);if(index>=numRows) index=(numRows-1)-(index-numRows+1);str_arr[index]+=s.charAt(i);}String res = "";for (String a: str_arr) {res += a;}return res;
}