Leetcode–6. Z 字形变换 [2020.9.8]
前言
这题我一开始用自己的方法,利用已知行数,将Z分割成多组,每组为
2
n
−
2
2n-2
2n−2个元素。将s对应元素下标对
2
n
−
2
2n-2
2n−2取余,然后根据余数就能够判断该数在Z字的哪一行,将其放入相应的字符串中,最后将各个字符串合并就可以获得具体的答案。但是时间与空间的效率并不高,并且由于数字下标从0开始,如果不注意细节很容易出错
题解的思路其实和我的也类似,但是多设置了一个flag=-1,在
i
=
0
i=0
i=0与
i
=
n
u
m
R
o
w
−
1
i=numRow-1
i=numRow−1处设置标记,此时flag=-flag,这样通过i+flag就能得到当前元素所作的行号。
题目
代码
/*解法1*/
class Solution {
public:
string convert(string s, int numRows) {
int l = s.length();
if(numRows==1) //如果行数为1直接返回
return s;
string res="";
string r[numRows]; //行字符串数组
for(int i=0; i<numRows; i++)
r[i]="";
for(int i=0; i<l; i++){
int tag = i%(2*numRows-2); //取余数
if(tag<numRows)
r[tag].push_back(s[i]); //反向点前
else
r[2*numRows-tag-2].push_back(s[i]); //反向点后
}
for(int i=0; i<numRows; i++)
res = res+r[i];
return res;
}
};
/*解法二*/
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1)
return s;
string res="";
string r[numRows];
int flag=-1,i=0,l=s.length();
for(int j=0; j<l; j++){
if(i==0||i==numRows-1)//注意反向点
flag = -flag;
r[i].push_back(s[j]);
i = i+flag;
}
for(int i=0; i<numRows; i++)
res = res + r[i];
return res;
}
};
/*解法三,以numRow-1为一组*/
class Solution {
public:
string convert(string s, int numRows) {
vector<string> temp(numRows);
string res;
if(s.empty() || numRows < 1) return res;
if(numRows == 1) return s;
for(int i = 0; i < s.size(); i++){
int ans = i / (numRows-1);
int cur = i % (numRows-1);
if(ans % 2 == 0){ //结果为偶数或0
temp[cur].push_back(s[i]); //按余数正序保存
}
if(ans % 2 != 0){ //结果为奇数
temp[numRows-cur-1].push_back(s[i]); //按余数倒序保存
}
}
for(int i = 0; i < temp.size(); i++){
res += temp[i];
}
return res;
}
};
附录
- 向字符串尾放字符用push_back()
- 注意numrow=1这种情况的处理
- Z字抖动的特点在于设定flag,并在反向点取反