一、题目描述
本题目的:将一个给定的字符串,按照Z字形排列,在遍历时得到一个新的字符串。
1.题目内容
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
原题链接:https://leetcode.cn/problems/zigzag-conversion/
2.样例
二、解决方案
算法流程:
- 遍历原字符串,将每个字符分别添加到对应“行”中;
- 当遇到数据流转折点,即第一行、最后一行时,更改数据流方向,通过设置一个标志变量flag来实现;
- 更新当前字符所对应的“行”;
其中当传入行数rows=1时,直接返回原字符串即可,核心代码处理rows>1的情况。
看个例子:
红色箭头表示数据流的方向,遍历字符串时,每当遇到第一行或者最后一行时,数据流的去向就发生一次变化,当前字符所对应行的下标遵循:0,1,…,rows-1,…,1,0的循环。
这里使用i来控制当前字符对应的行;j表示遍历字符串中字符对应的下标;而flag则用来控制数据流的方向,每当i=0或者i=rows-1时就对自身取反,即flag=-flag。
1.Java代码
public class ZConvert {
public static String stringConvert(String str,int rows) {
if(rows==1){
return str;
}
List<StringBuilder> rowsStr=new ArrayList<StringBuilder>(); // 按行存储新的内容形式
for(int n=0;n<rows;n++){
rowsStr.add(new StringBuilder());
}
int i=0; // 控制当前字符对应的行
int flag=-1; // 控制z形排列时的数据方向
int j=0; //控制当前遍历的字符
while (j<str.length()){ // 遍历字符串
// 核心代码
rowsStr.get(i).append(str.charAt(j));
if(i==0||i==rows-1){
flag=-flag; // 第一行或者最后一行数据流方向反转
}
i+=flag; // 更新当前字符对应行的下标
j++; //更新遍历字符的下标
}
// System.out.println(rowsStr.toString());
StringBuilder newStr=new StringBuilder(); //拼接得到新的字符串
for(int r=0;r<rows;r++){
newStr.append(rowsStr.get(r).toString());
}
return newStr.toString();
}
public static void main(String[] args) {
String str="PAYPALISHIRING";
int rows=5;
System.out.println(stringConvert(str,rows));
}
}
2.Python代码
'''
LeetCode6:Z字形变换
'''
def str_convert(string,rows_num):
if rows_num==1:
return string
rows_str=[]
for i in range(0,rows_num):
rows_str.append('')
i=0
flag=-1
for c in string:
rows_str[i]+=c
if i==0 or i==rows_num-1:
flag=-flag
i+=flag
new_str=''
for item in rows_str:
new_str+=item
return new_str
if __name__=='__main__':
s = "PAYPALISHIRING"
rows = 5
print(str_convert(s,rows))
解题思路参考解答:https://leetcode.cn/problems/zigzag-conversion/solution/zzi-xing-bian-huan-by-jyd/
我只能说大佬神佬啊,自己写了好久死活写不对,刚开始一直在找字符串元素下标之间的规律,人裂开了。看到大佬的解答,直接就是一个醍醐灌顶!!