题目
将字符串 “PAYPALISHIRING” 以Z字形排列成给定的行数:
P A H N
A P L S I I G
Y I R
之后从左往右,逐行读取字符:“PAHNAPLSIIGYIR”
实现一个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例
示例1
输入: s = “PAYPALISHIRING”, numRows = 3
输出: “PAHNAPLSIIGYIR”
示例2
输入: s = “PAYPALISHIRING”, numRows = 4
输出: “PINALSIGYAHRPI”
解释:
P I N
A L S I G
Y A H R
P I
题目分析
定义numRows大小的字符串数组,遍历原字符串,按规律挨个将单个字符放入字符串数组。用 i 迭代原字符串,用 j 迭代字符串数组,它们之间的关系:(假设numRows=3,s = “PAYPALISHIRING”)
i : 0 1 2 3 4 5 6 7 8 9 10 11 12 13...
j : 0 1 2 1 0 1 2 1 0 1 2 1 0 1...
对应的 j 在 0 的基础上加1,加1,减1,减1,加1,加1,减1,减1······
对应Z字形:
P A H N
A P L S I I G
Y I R
当 i 为numRows-1的倍数时,j 与1做运算的状态(加或减)会发生改变,所以可以在遍历字符串的循环外定义一个变量初始值为1,让 j 始终与这个变量做运算,当 i 为numRows-1的倍数时,让这个数更新为自己的相反数。最后将字符串数组按行连接为一个字符串返回就好啦
需要注意的是: 循环中几行代码的先后顺序不能混,先将原字符串中遍历到的字符放入字符串数组中 j 位置的字符串的下一个字符位置,然后判断条件 i 为numRows-1的整数倍是否符合,符合就让标志位变量更新为自己的相反数,再让 j 与这个变量做运算。否则会发生数组越界异常。
代码
class Solution {
public String convert(String s, int numRows) {
if(numRows == 1) //numRows为1直接返回原字符串
return s;
String[] str = new String[numRows]; //用字符串数组实现,有几行数组大小就是几
for(int i = 0; i < str.length; i++)
str[i] = ""; //初始化
int flag = 1; //定义标志位
for(int i = 0, j = 0; i < s.length(); i++) {
str[j] = str[j].concat(String.valueOf(s.charAt(i)));
if(i != 0 && i%(str.length-1) == 0)
flag = -flag; //条件符合就让标志位变量更新为自己的相反数
j += flag; //j 与标志位变量做运算
}
String convert = "";
for(int i = 0; i < str.length; i++)
convert = convert.concat(str[i]);
return convert;
}
}